diff --git a/gemeinsamforschen/pom.xml b/gemeinsamforschen/pom.xml index 5fa0d0f8e5b50917e71d3cd24259770441115c28..e23a29992f526e80c3722a35ceb67be4d603cc01 100644 --- a/gemeinsamforschen/pom.xml +++ b/gemeinsamforschen/pom.xml @@ -165,6 +165,11 @@ <version>1.3.4</version> </dependency> + <dependency> + <groupId>com.atlassian.commonmark</groupId> + <artifactId>commonmark</artifactId> + <version>0.11.0</version> + </dependency> </dependencies> </project> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java index 8ac3bfef0ccda8396305bdb23db71ec9c872bb70..e5593b493426458b501b6e008f2cb26f87c539b2 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java @@ -23,8 +23,9 @@ public class Menu extends SimpleTagSupport { out.println("<div id=\"sidebar-wrapper\">\n" + " <ul class=\"sidebar-nav\">\n" + " <li class=\"sidebar-brand\"><a href=\"overview-student.jsp?token="+token+"\">overview</a></li>\n" + + " <li><a href=\"profile.jsp?token="+token+"\">Profil</a></li>\n" + " <li><a href=\"Quiz.jsp?token="+token+"\">Quizfrage</a></li>\n" + - " <li><a href=\"#\">ePortfolio</a></li>\n" + + " <li><a href=\"eportfolio.jsp?token="+token+"\">ePortfolio</a></li>\n" + " <li><a href=\"#\">Beitrag</a></li>\n" + " <li><a href=\"finalAssessments.jsp?token="+token+"\">Bewertung</a></li>\n" + " <li><a href=\"../index.jsp\">Logout</a></li>\n" + diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..5d25997fb52658f8d3f209c289677286659ccb59 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java @@ -0,0 +1,25 @@ +package unipotsdam.gf.core.management.utils; + +import org.commonmark.node.Node; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.html.HtmlRenderer; + +/** + * Utility class to convert markdown to html and back + */ + +public class MarkdownUtils { + + /** + * Converts a markdown text to html + * @param markdown markdown text + * @return html text + */ + public static String convertMarkdownToHtml(String markdown){ + Parser parser = Parser.builder().build(); + Node document = parser.parse(markdown); + HtmlRenderer renderer = HtmlRenderer.builder().build(); + return renderer.render(document); + } + +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java new file mode 100644 index 0000000000000000000000000000000000000000..65a17d1fea783d016f0422414d5dbed66ee4b671 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java @@ -0,0 +1,117 @@ +package unipotsdam.gf.modules.journal.model; + + +import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier; + +import static unipotsdam.gf.core.management.utils.MarkdownUtils.convertMarkdownToHtml; + +/** + * Model Class for the learnig journal of the e-portfolio + */ +public class Journal { + + private long id; + private StudentIdentifier studentIdentifier; + private String creator; + private String entryHTML; + private String entryMD; + private long timestamp; + private Visibility visibility; + private String category;//TODO enum + + public Journal() {} + + public Journal(long id, StudentIdentifier studentIdentifier, String entry, long timestamp, Visibility visibility, String category) { + this.id = id; + this.studentIdentifier = studentIdentifier; + // TODO setName per StudentID + this.entryHTML = convertMarkdownToHtml(entry); + this.entryMD = entry; + this.timestamp = timestamp; + this.visibility = visibility; + this.category = category; + } + + public void setEntry(String entry){ + this.entryMD = entry; + this.entryHTML = convertMarkdownToHtml(entry); + } + + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public StudentIdentifier getStudentIdentifier() { + return studentIdentifier; + } + + public void setStudentIdentifier(StudentIdentifier studentIdentifier) { + this.studentIdentifier = studentIdentifier; + } + + public String getEntryHTML() { + return entryHTML; + } + + public void setEntryHTML(String entryHTML) { + this.entryHTML = entryHTML; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public Visibility getVisibility() { + return visibility; + } + + public void setVisibility(Visibility visibility) { + this.visibility = visibility; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getEntryMD() { + return entryMD; + } + + public void setEntryMD(String entryMD) { + this.entryMD = entryMD; + } + + @Override + public String toString() { + return "Journal{" + + "id=" + id + + ", studentIdentifier=" + studentIdentifier + + ", creator='" + creator + '\'' + + ", entryHTML='" + entryHTML + '\'' + + ", timestamp=" + timestamp + + ", visibility=" + visibility + + ", category='" + category + '\'' + + '}'; + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/JournalFilter.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/JournalFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..07fd1274e0420554670449b108225b4697c198f5 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/JournalFilter.java @@ -0,0 +1,6 @@ +package unipotsdam.gf.modules.journal.model; + +public enum JournalFilter { + + ALL,OWN +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java new file mode 100644 index 0000000000000000000000000000000000000000..7c73443a81d372bfe5bdc2cbc43a67a241e95c43 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java @@ -0,0 +1,133 @@ +package unipotsdam.gf.modules.journal.model; + +import unipotsdam.gf.core.management.project.Project; + +import java.util.ArrayList; +import java.util.Map; + +import static unipotsdam.gf.core.management.utils.MarkdownUtils.convertMarkdownToHtml; + +/** + * Model class for the project descriptionHTML of the e portfolio + */ + +public class ProjectDescription { + + private long id; + private String name; + private String descriptionHTML; + private String descriptionMD; + private boolean open; + private Project project; + private Map<String,String> links; + private ArrayList<String> group; + private long timestamp; + + public ProjectDescription() { + } + + public ProjectDescription(long id, String name, String description, Project project, Map<String, String> links, ArrayList<String> group, long timestamp) { + this.id = id; + this.name = name; + this.descriptionHTML = convertMarkdownToHtml(description); + this.descriptionMD =description; + this.project = project; + this.links = links; + this.group = group; + this.timestamp = timestamp; + this.open =true; + } + + public void setDescription (String description){ + this.descriptionMD = description; + this.descriptionHTML = convertMarkdownToHtml(description); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescriptionHTML() { + return descriptionHTML; + } + + public void setDescriptionHTML(String descriptionHTML) { + this.descriptionHTML = descriptionHTML; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public Map<String, String> getLinks() { + return links; + } + + public void setLinks(Map<String, String> links) { + this.links = links; + } + + public ArrayList<String> getGroup() { + return group; + } + + public void setGroup(ArrayList<String> group) { + this.group = group; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public boolean isOpen() { + return open; + } + + public void setOpen(boolean open) { + this.open = open; + } + + public String getDescriptionMD() { + return descriptionMD; + } + + public void setDescriptionMD(String descriptionMD) { + this.descriptionMD = descriptionMD; + } + + + @Override + public String toString() { + return "ProjectDescription{" + + "id=" + id + + ", name='" + name + '\'' + + ", descriptionHTML='" + descriptionHTML + '\'' + + ", descriptionMD='" + descriptionMD + '\'' + + ", open=" + open + + ", project=" + project + + ", links=" + links + + ", group=" + group + + ", timestamp=" + timestamp + + '}'; + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Visibility.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Visibility.java new file mode 100644 index 0000000000000000000000000000000000000000..ce31ce305802ac036a27a2d452ee86926aac472f --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Visibility.java @@ -0,0 +1,4 @@ +package unipotsdam.gf.modules.journal.model; + +public enum Visibility { ALL, GROUP, DOZENT, MINE +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyJournalService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyJournalService.java new file mode 100644 index 0000000000000000000000000000000000000000..d005bbd9dd17092bd316eea835c49ce5f8c66661 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyJournalService.java @@ -0,0 +1,159 @@ +package unipotsdam.gf.modules.journal.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier; +import unipotsdam.gf.modules.journal.model.Journal; +import unipotsdam.gf.modules.journal.model.JournalFilter; +import unipotsdam.gf.modules.journal.model.Visibility; + +import java.util.ArrayList; +import java.util.Calendar; + +/** + * Service Implementation to test rest, no Database operations + */ + +public class DummyJournalService implements JournalService { + + private Logger log = LoggerFactory.getLogger(DummyJournalService.class); + + + private Calendar cal = Calendar.getInstance(); + + private long id = 4; + + private ArrayList<Journal> journals = new ArrayList<>(); + + public DummyJournalService(){ + + resetList(); + } + + @Override + public Journal getJournal(String id) { + for (Journal j : journals) { + if(j.getId() == Long.valueOf(id)){ + return j; + } + } + return null; + } + + @Override + public ArrayList<Journal> getAllJournals(String student, String project, JournalFilter filter) { + log.debug(">> get all journals(" + student + "," + project + "," + filter + ")"); + + ArrayList<Journal> result = new ArrayList<>(); + + for (Journal j: journals) { + + //always show own Journals + if(j.getStudentIdentifier().getStudentId().equals(student)){ + result.add(j); + }else{ + + // if Visibility All, show if Filter allows it + if (j.getVisibility() == Visibility.ALL && filter==JournalFilter.ALL){ + result.add(j); + } + + //If Visibility Group, show if student is in group and filter allows it + //TODO: project != Group, for testing ok, change for real Service + if (j.getVisibility()== Visibility.GROUP && j.getStudentIdentifier().getProjectId().equals(project) && filter == JournalFilter.ALL){ + result.add(j); + } + + //TODO if Dozent + } + + } + log.debug("<< get all journals(" + student , "," + project + ")"); + + return result; + } + + @Override + public ArrayList<Journal> getAllJournals(String student, String project) { + return getAllJournals(student,project,JournalFilter.ALL); + } + + @Override + public boolean saveJournal(long id, String student, String project, String text, String visibility, String category) { + if (id == -1){ + + StudentIdentifier studentId = new StudentIdentifier(student,project); + journals.add(new Journal(this.id++, studentId, text , cal.getTimeInMillis(), stringToVisibility(visibility) , category)); + + } else { + for (Journal j : journals){ + if(j.getId() == id){ + j.setEntry(text); + j.setVisibility(stringToVisibility(visibility)); + j.setCategory(category); + } + } + resetList(); + } + return true; + } + + @Override + public boolean deleteJournal(long id) { + for (Journal j : journals) { + if (j.getId() == id) { + journals.remove(j); + return true; + } + } + return false; + } + + @Override + public void closeJournal(String journal) { + + } + + private Visibility stringToVisibility(String visibility) { + // If String does not match enum IllegalArgumentException + Visibility v ; + try{ + v = Visibility.valueOf(visibility); + }catch (IllegalArgumentException e){ + v = Visibility.MINE; + log.debug("Illegal argument for visibility, default to MINE"); + } + return v; + } + + private void resetList() { + + StudentIdentifier studentIdentifier = new StudentIdentifier("0","0"); + StudentIdentifier studentIdentifier2 = new StudentIdentifier("0","1"); + + String test = "**nec** nec facilisis nibh, sed sagittis tortor. Suspendisse vel felis ac leo dignissim efficitur. Nunc non egestas eros, sit amet vestibulum nunc. Sed bibendum varius molestie. Proin augue mauris, mollis sed efficitur efficitur, sagittis quis eros. Praesent tincidunt tincidunt porttitor. Maecenas quis ornare tellus. Nunc euismod vestibulum neque, sed luctus neque convallis in. Duis molestie ex ut nunc dignissim condimentum ut vitae dui. Vestibulum diam lorem, eleifend sit amet lobortis nec, vulputate a leo. In nec ante felis. Maecenas interdum nunc et odio placerat fringilla. Aenean felis purus, mollis id lectus non, fringilla tincidunt mi. Nunc sed rutrum ex, vel tempus odio."; + + Journal j1 = new Journal(0,studentIdentifier,test, cal.getTimeInMillis() , Visibility.ALL, "Recherche"); + j1.setCreator("Test Test"); + Journal j2 = new Journal(1,studentIdentifier,test, cal.getTimeInMillis() , Visibility.MINE, "Untersuchungskonzept"); + j2.setCreator("Test Test"); + Journal j3 = new Journal(2,studentIdentifier,test, cal.getTimeInMillis() , Visibility.GROUP, "Methodik"); + j3.setCreator("Test Test"); + Journal j4 = new Journal(3,studentIdentifier,test, cal.getTimeInMillis() , Visibility.DOZENT ,"Recherche"); + j4.setCreator("Test Test"); + Journal j5 = new Journal(4,studentIdentifier2,test, cal.getTimeInMillis() , Visibility.GROUP, "Durchführung"); + j5.setCreator("ASD DSA"); + + journals = new ArrayList<>(); + + journals.add(j1); + journals.add(j2); + journals.add(j3); + journals.add(j4); + journals.add(j5); + + } + + + +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyProjectDescription.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyProjectDescription.java new file mode 100644 index 0000000000000000000000000000000000000000..83d23f00d26a72cadeaecbd95f3b68d9d6d83704 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/DummyProjectDescription.java @@ -0,0 +1,63 @@ +package unipotsdam.gf.modules.journal.service; + +import unipotsdam.gf.core.management.project.Project; +import unipotsdam.gf.modules.journal.model.ProjectDescription; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +public class DummyProjectDescription implements ProjectDescriptionService { + + private ProjectDescription testProject; + + public DummyProjectDescription(){ + + HashMap<String,String> link = new HashMap<>(); + link.put("Test", "www.test.de"); + link.put("Google", "www.google.de"); + + ArrayList<String> group = new ArrayList<>(); + group.add("Test Person"); + group.add("Person Test"); + + String desc = " *Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet* \n" + + "\n" + + "**Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.** \n" + + "\n" + + "\n" + + "\n" + + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \n" + + "\n" + + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. "; + + testProject = new ProjectDescription(0,"Eine kreative Ãœberschrift",desc, new Project(), link, group, new Date().getTime()); + } + + + @Override + public ProjectDescription getProject(String project) { + return testProject; + } + + @Override + public void saveProjectText(String text) { + testProject.setDescription(text); + } + + @Override + public void addLink(String link, String name) { + //convert String to List + //setLinks + } + + @Override + public void deleteLink(String link) { + + } + + @Override + public void closeDescription(String desc) { + + } +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/JournalService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/JournalService.java new file mode 100644 index 0000000000000000000000000000000000000000..c247215c82bb98e7f41d807fb22a8c9a2f87d360 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/JournalService.java @@ -0,0 +1,59 @@ +package unipotsdam.gf.modules.journal.service; + +import unipotsdam.gf.modules.journal.model.Journal; +import unipotsdam.gf.modules.journal.model.JournalFilter; + +import java.util.ArrayList; + +/** + * Service for learning Journal + */ + +public interface JournalService { + + /** + * Returns a specific Journal + * @param id id of Journal + * @return JSON of Journal + */ + Journal getJournal(String id); + + /** + * Returns all Journals for a student, filtered whether only own or all Journals are requested + * @param student the requested student + * @param project the requested project + * @param filter OWN or ALL + * @return Json of all Journals + */ + ArrayList<Journal> getAllJournals(String student, String project, JournalFilter filter); + + /** + * Returns all Journals for a student + * @param student the requested student + * @param project the requested project + * @return Json of all Journals + */ + ArrayList<Journal> getAllJournals(String student, String project); + + /** + * Saves or edits a Journal + * @param id id, -1 if new Journal + * @param student owner of the Journal + * @param project associated Project + * @param text content of the Journal + * @param visibility visibility of the Journal + * @param category category of the Journal + * @return true if success + */ + boolean saveJournal(long id, String student, String project, String text, String visibility, String category); + + /** + * deletes a Journal + * @param id id of the Journal + * @return true if success + */ + boolean deleteJournal(long id); + + + void closeJournal(String journal); +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/ProjectDescriptionService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/ProjectDescriptionService.java new file mode 100644 index 0000000000000000000000000000000000000000..dfe3966fe100e53173466b5d66ecf2861d5d9e15 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/service/ProjectDescriptionService.java @@ -0,0 +1,21 @@ +package unipotsdam.gf.modules.journal.service; + +import unipotsdam.gf.modules.journal.model.ProjectDescription; + +/** + * Service for learning Journal + */ + +public interface ProjectDescriptionService { + + + ProjectDescription getProject(String project); + + void saveProjectText(String text); + + void addLink(String link, String name); + + void deleteLink(String link); + + void closeDescription(String desc); +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/JournalView.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/JournalView.java new file mode 100644 index 0000000000000000000000000000000000000000..218ad0706a6b71c2ec61726f48034e9db002d39f --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/JournalView.java @@ -0,0 +1,174 @@ +package unipotsdam.gf.modules.journal.view; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import unipotsdam.gf.modules.journal.model.Journal; +import unipotsdam.gf.modules.journal.model.JournalFilter; +import unipotsdam.gf.modules.journal.service.DummyJournalService; +import unipotsdam.gf.modules.journal.service.JournalService; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/** + * View for the learning journal + * + * TODO error handling, (maybe) method to change visibility + */ + +@Path("/journal") +public class JournalView { + + private Logger log = LoggerFactory.getLogger(JournalView.class); + private JournalService journalService = new DummyJournalService(); + + /** + * Returns a specific Journal + * @param id id of Journal + * @return JSON of Journal + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{id}") + public Response getJournal (@PathParam("id") String id){ + + log.debug(">>> getJournal: id=" + id ); + + Journal result = journalService.getJournal(id); + + log.debug("<<< getJournal: result=" + result.toString()); + + return Response.ok(result).build(); + } + + /** + * Returns all Journals for a student, filtered whether only own or all Journals are requested + * @param student the requested student + * @param project the requested project + * @param filter OWN or ALL + * @return Json of all Journals + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/journals/{student}/{project}/{filter}") + public Response getAllJournals (@PathParam("student") String student, @PathParam("project") String project, @PathParam("filter") String filter){ + + log.debug(">>> getJournals: student=" + student + " project=" + project +" filter=" + filter ); + + JournalFilter filt = (filter.equals("ALL")) ? JournalFilter.ALL:JournalFilter.OWN; + ArrayList<Journal> result = journalService.getAllJournals(student,project,filt); + + log.debug(">>> getJournals: size=" + result.size()); + + return Response.ok(result).build(); + } + + /** + * Returns all Journals for a student + * @param student the requested student + * @param project the requested project + * @return Json of all Journals + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/journals/{student}/{project}") + public Response getAllJournals (@PathParam("student") String student, @PathParam("project") String project){ + + log.debug(">>> getJournals: student=" + student + " project=" + project ); + + ArrayList<Journal> result = journalService.getAllJournals(student,project); + + log.debug(">>> getJournals: size=" + result.size()); + + return Response.ok(result).build(); + } + + /** + * Saves or edits a Journal + * @param id id, -1 if new Journal + * @param student owner of the Journal + * @param project associated Project + * @param text content of the Journal + * @param visibility visibility of the Journal + * @param category category of the Journal + * @return Empty Response + */ + + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + @Path("/save") + public Response saveJournal(@FormParam("id") long id, @FormParam("student") String student, + @FormParam("project") String project, @FormParam("text") String text, + @FormParam("visibility") String visibility, @FormParam("category") String category) { + + log.debug(">>> saveJournal"); + + journalService.saveJournal(id, student, project, text, visibility, category); + + //TODO token + URI location; + try { + location = new URI("../pages/eportfolio.jsp?token=test"); + log.debug("<<< saveJournal: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("saveJournal: redirect failed" ); + } + + log.debug("<<< saveJournal"); + + return Response.ok().build(); + + } + + /** + * deletes a Journal + * @param id id of the Journal + * @return Empty Response + */ + + @GET + @Produces(MediaType.TEXT_PLAIN) + @Path("/delete/{id}") + public Response deleteJournal(@PathParam("id") long id) { + + log.debug(">>> deleteJournal: id=" + id); + + journalService.deleteJournal(id); + + log.debug("<<< deleteJournal"); + + return Response.ok().build(); + } + + //close journal + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Path("/close") + public Response closeJournal(String journal){ + log.debug(">>> closeJournal: " + journal); + + journalService.closeJournal(journal); + //TODO token + try { + URI location = new URI("../pages/eportfolio.jsp?"); + log.debug("<<< closeJournal: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("closeJournal: redirect failed" ); + } + + log.debug("<<< closeJournal"); + return Response.ok().build(); + } + +} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/ProjectDescriptionView.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/ProjectDescriptionView.java new file mode 100644 index 0000000000000000000000000000000000000000..ba29c2592521befb9c182edad18ec13d0b10b288 --- /dev/null +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/view/ProjectDescriptionView.java @@ -0,0 +1,138 @@ +package unipotsdam.gf.modules.journal.view; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import unipotsdam.gf.modules.journal.model.ProjectDescription; +import unipotsdam.gf.modules.journal.service.DummyProjectDescription; +import unipotsdam.gf.modules.journal.service.ProjectDescriptionService; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * View for the project description + * + * TODO error handling + */ + +@Path("/projectdescription") +public class ProjectDescriptionView { + + private Logger log = LoggerFactory.getLogger(ProjectDescriptionView.class); + private ProjectDescriptionService descriptionService = new DummyProjectDescription(); + + //get Description + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{project}") + public Response getProjectDescription(@PathParam("project") String project){ + log.debug(">>> getProjectDescription: " + project); + + ProjectDescription result = descriptionService.getProject(project); + + log.debug(">>> getProjectDescription"); + return Response.ok(result).build(); + } + + //save Description + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.TEXT_PLAIN) + @Path("/saveText") + public Response saveProjectText(@FormParam("student")String student,@FormParam("project")String project,@FormParam("text")String text){ + log.debug(">>> saveText: " + text); + + descriptionService.saveProjectText(text); + + //TODO token + try { + URI location = new URI("../pages/eportfolio.jsp?token=test"); + log.debug("<<< saveText: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("saveText: redirect failed" ); + } + + log.debug("<<< saveText");log.debug(">>> saveText"); + + return Response.ok().build(); + } + + //add Link + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Path("/addLink") + public Response addLink(@FormParam("link") String link, @FormParam("name") String name){ + log.debug(">>> addLink: " + name + ":" + link); + + descriptionService.addLink(link, name ); + + + try { + URI location = new URI("../pages/eportfolio.jsp"); + log.debug("<<< addLink: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("addLink: redirect failed" ); + } + + log.debug(">>> addLink"); + + return Response.ok().build(); + } + + + //delete Link + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Path("/deleteLink") + public Response deleteLink(String link){ + log.debug(">>> deleteLink: " + link); + + descriptionService.deleteLink(link); + //TODO token + try { + URI location = new URI("../pages/eportfolio.jsp"); + log.debug("<<< deleteLink: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("deleteLink: redirect failed" ); + } + + log.debug("<<< deleteLink"); + return Response.ok().build(); + } + + //close descr + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Path("/close") + public Response closeDescription(String desc){ + log.debug(">>> closeDescription: " + desc); + + descriptionService.closeDescription(desc); + //TODO token + try { + URI location = new URI("../pages/eportfolio.jsp"); + log.debug("<<< closeDescription: redirect to " +location.toString()); + return Response.temporaryRedirect(location).build(); + + } catch (URISyntaxException e) { + e.printStackTrace(); + log.debug("closeDescription: redirect failed" ); + } + + log.debug("<<< closeDescription"); + return Response.ok().build(); + } + +} diff --git a/gemeinsamforschen/src/main/resources/log4j2.xml b/gemeinsamforschen/src/main/resources/log4j2.xml index fccc9f408e851d4bf039588024aba0cea9771354..44a5bde6b293c2233cb735339118c356d16db9dc 100644 --- a/gemeinsamforschen/src/main/resources/log4j2.xml +++ b/gemeinsamforschen/src/main/resources/log4j2.xml @@ -6,7 +6,7 @@ </Console> </Appenders> <Loggers> - <Root level="info"> + <Root level="debug"> <AppenderRef ref="Console"/> </Root> </Loggers> diff --git a/gemeinsamforschen/src/main/webapp/assets/css/create-journal.css b/gemeinsamforschen/src/main/webapp/assets/css/create-journal.css new file mode 100644 index 0000000000000000000000000000000000000000..1dd6779c31e8b87cacda2f728638f7d1bca4ddb0 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/css/create-journal.css @@ -0,0 +1,27 @@ +.journal-form-container { + display: grid; + grid-gap: 10px; + grid-template-columns: 1fr 1fr 1fr; + grid-template-areas: + "visibility category ..." + "editor editor editor" + "buttons ... ...." + ; +} + +.journal-form-visibility{ + grid-area: visibility; +} + +.journal-form-category{ + grid-area: category; +} + +.journal-form-editor{ + grid-area: editor; +} + +.journal-form-buttons{ + grid-area: buttons; +} + diff --git a/gemeinsamforschen/src/main/webapp/assets/css/e-portfolio.css b/gemeinsamforschen/src/main/webapp/assets/css/e-portfolio.css new file mode 100644 index 0000000000000000000000000000000000000000..c987b53b4701008b110f05cfe674ae9fc5d02f15 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/css/e-portfolio.css @@ -0,0 +1,64 @@ +.journal-description-container{ + display: grid; + grid-gap: 10px; + grid-template-columns: 2fr 1fr 15%; + grid-template-areas: + "title edit group" + "text text links" + "text text ..." +; +} + +.journal-description-title{ + grid-area:title; +} + +.journal-description-edit{ + grid-area:edit; +} + +.journal-description-group{ + grid-area:group; +} + +.journal-description-text{ + grid-area:text; +} + +.journal-description-links{ + grid-area:links; +} + +.journal-container{ + display: grid; + grid-gap: 10px; + grid-template-columns: 1fr 1fr 2fr 2fr 15%; + grid-template-areas: + "name date category edit ..." + "avatar text text text ..." + ; +} + +.journal-name{ + grid-area:name; +} + +.journal-date{ + grid-area:date; +} + +.journal-category{ + grid-area:category; +} + +.journal-edit{ + grid-area:edit; +} + +.journal-avatar{ + grid-area:avatar; +} + +.journal-text{ + grid-area:text; +} \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/assets/css/editDescription.css b/gemeinsamforschen/src/main/webapp/assets/css/editDescription.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css b/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css new file mode 100644 index 0000000000000000000000000000000000000000..16ff7e4ce9ecbb4d462b22445ac2bbe064279705 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/css/upload-unstructured.css @@ -0,0 +1,143 @@ +ol { + padding: 0px; + margin: 0px; + list-style-type: none; +} +.mainpage { + display: flex; + box-sizing: border-box; + font-family: Arial; + height: 100%; +} +.rightcolumn { + float: right; + width: 25%; + display: inline-block; + /* background-color: blue; */ +} +.leftcolumn { + float: left; + width: 75%; + display: inline-block; + /* background-color: yellow; */ +} +.rightcontent { + margin: 10px; +} +.leftcontent { + margin: 10px; + /* background-color: white; */ +} +.spacing { + height: 10px; + /* background-color: orange; */ +} + +.annotation-card { + width: 100%; + box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); + transition: 0.3s; + border-radius: 5px; + display: inline-block; + background-color: white; +} +.annotation-card:hover { + box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); +} +.annotation-header { + padding: 5px; + display: flex; + flex-wrap: wrap; + align-items: center; + border-top-right-radius: 5px; + border-top-left-radius: 5px; + color: white; } +.annotation-header i { + font-size: 11px; +} +.annotation-header span { + font-size: 11px; + margin-left: 5px; + margin-right: 5px; +} +.annotation-header a:link { + color: white; + text-decoration: none; +} +.annotation-header a:visited { + color: white; + text-decoration: none; +} +.annotation-header a:active { + color: white; + text-decoration: none; +} +.annotation-header a:hover { + color: #e6e6e6; + text-decoration: none; +} +.annotation-header-title { + display: flex; + flex-flow: column; + width: calc(100% - 40px); +} +.annotation-header-toggle { + height: 40px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} +.annotation-body { + padding: 8px; + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; +} +.annotation-body p { + margin: 0px; + font-size: 13px; +} +.overflow-hidden { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.annotation-footer { + padding: 5px; + padding-top: 0px; + text-align: right; + font-size: 9px; + color: lightgrey; + display: flex; +} +.annotation-footer span { + margin-left: 5px; +} +.annotation-footer-delete { + margin-right: 5px; + cursor: pointer; +} +.annotation-footer-date { + flex: 1 +} + + + +.unstructured-textarea { + resize: none; +} +.document-text-buttons { + margin-top: 10px; + display: inline; +} +.document-text-buttons-lock { + float: left; +} +.document-text-buttons-back { + float: left; +} +.document-text-buttons-save { + float: right; +} + diff --git a/gemeinsamforschen/src/main/webapp/assets/js/createJournal.js b/gemeinsamforschen/src/main/webapp/assets/js/createJournal.js new file mode 100644 index 0000000000000000000000000000000000000000..96130eb0a3e13aefa384e29a4eda8129f32faf4d --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/js/createJournal.js @@ -0,0 +1,40 @@ +function getQueryVariable(variable) +{ + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i=0;i<vars.length;i++) { + var pair = vars[i].split("="); + if(pair[0] == variable){return pair[1];} + } + return(false); +} + +$(document).ready(function() { + var journalID = getQueryVariable("journal"); + console.log(journalID); + if(journalID){ + $.ajax({ + url: "../rest/journal/"+journalID + }).then(function(data) { + $('#editor').append(data.entryMD); + + //TODO preselet in select tags + new InscrybMDE({ + element: document.getElementById("editor"), + spellChecker: false, + forceSync: true, + }); + + console.log(data); + + }); + } else { + new InscrybMDE({ + element: document.getElementById("editor"), + spellChecker: false, + forceSync: true, + }); + } + + +}) \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/assets/js/e-portfolio.js b/gemeinsamforschen/src/main/webapp/assets/js/e-portfolio.js new file mode 100644 index 0000000000000000000000000000000000000000..1969dcd03c16d28d19b42958c122f8d8d0425689 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/js/e-portfolio.js @@ -0,0 +1,126 @@ +//TODO Get student and project form context + +$(document).ready(function() { + $.ajax({ + url: "../rest/projectdescription/0" + }).then(function(data) { + $('.journal-description-title').append('<h2>' + data.name + '</h2>'); + $('.journal-description-text').append(data.descriptionHTML); + for(var link in data.links){ + $('.journal-description-links').append('<button class="btn btn-default btn-xs" onclick=\'linkLoeschen("'+link+'")\'> <i class="fa fa-trash" aria-hidden="true" ></i></button><a href=\' + data.links[link] + \'>' + link + '</a> <br/>'); + } + $('.journal-description-links').append('<button type="button" class="btn btn-default btn-xs" data-toggle="modal" data-target="#addLinkModal"><i class="fa fa-plus" aria-hidden="true"></i></button>'); + + for(var g in data.group){ + $('.journal-description-group').append(data.group[g]+ '<br/>'); + + } + console.log(data); + }); + + $.ajax({ + url: "../rest/journal//journals/0/0" + }).then(function(data) { + loadJournals(data); + console.log(data); + }); + +}); + +function timestampToDateString(timestamp) { + var date = new Date(timestamp); + return date.toLocaleString("de-DE"); +} + +function filterJournals() { + var filter = $( '#journalfilter option:selected' ).val(); + + $('.journal').empty(); + + $.ajax({ + url: "../rest/journal//journals/0/0/"+filter + }).then(function(data) { + loadJournals(data); + console.log(data); + + }); + +} + +function loadJournals(data) { + for (var journal in data) { + $('.journal').append( + '<div class="journal-container">' + + '<div class="journal-avatar">' + + 'getBild' + + '</div>' + + '<div class="journal-date"> ' + + timestampToDateString(data[journal].timestamp) + + '</div>' + + '<div class="journal-name">' + + data[journal].creator + + '</div>' + + '<div class="journal-category">' + + data[journal].category + + '</div>' + + '<div class="journal-edit" align="right">' + + '<a class="btn btn-default btn-sm" href="createJournal.jsp?token=test&journal=' + data[journal].id + '"><i class="fa fa-pencil"></i> Bearbeiten</a>' + + '<a class="btn btn-default btn-sm" data-toggle="modal" data-target="#closeJournalModal"><i class="fa fa-check-square" aria-hidden="true"></i>Abschließen</a>' + + '</div>' + + '<div class="journal-text">' + + data[journal].entryHTML + + '</div>' + + '</div><br><br>') + }}; + + +function linkLoeschen(name) { + console.log("löschen" + name); + $.ajax({ + type: "POST", + url: "../rest/projectdescription/deleteLink", + data: JSON.stringify(name), + contentType: "application/json; charset=utf-8", + crossDomain: true, + dataType: "json", + success: function (data, status, jqXHR) { + + alert(success); + } + }); + +} + +function closeJournal(journal) { + console.log("löschen" + journal); + $.ajax({ + type: "POST", + url: "../rest/journal/close", + data: JSON.stringify(journal), + contentType: "application/json; charset=utf-8", + crossDomain: true, + dataType: "json", + success: function (data, status, jqXHR) { + + alert(success); + } + }); + +} + +function closeJournal(description) { + console.log("löschen" + description); + $.ajax({ + type: "POST", + url: "../rest/projectdescription/close", + data: JSON.stringify(description), + contentType: "application/json; charset=utf-8", + crossDomain: true, + dataType: "json", + success: function (data, status, jqXHR) { + + alert(success); + } + }); + +} \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/assets/js/editDescription.js b/gemeinsamforschen/src/main/webapp/assets/js/editDescription.js new file mode 100644 index 0000000000000000000000000000000000000000..b6f6a893ac478a012bb160ea8854b0d38f38a46f --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/js/editDescription.js @@ -0,0 +1,17 @@ +$(document).ready(function() { + $.ajax({ + url: "../rest/projectdescription/0" + }).then(function(data) { + $('#editor').append(data.descriptionMD); + + //TODO preselet in select tags + new InscrybMDE({ + element: document.getElementById("editor"), + spellChecker: false, + forceSync: true, + }); + + console.log(data); + + }); +}) \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/assets/js/project-student.js b/gemeinsamforschen/src/main/webapp/assets/js/project-student.js index 9a7b01bf581634f5e54b27001da6f658bb8e01a7..ffc7facbdd443de53ce28d7faeb0cefd84298e7a 100644 --- a/gemeinsamforschen/src/main/webapp/assets/js/project-student.js +++ b/gemeinsamforschen/src/main/webapp/assets/js/project-student.js @@ -16,4 +16,8 @@ $(document).ready(function(){ $('.annotationview').click(function () { location.href="annotation-document.jsp?token="+getUserTokenFromUrl(); }); + + $('#btnUnstructuredUpload').click(function () { + location.href="upload-unstructured.jsp?token="+getUserTokenFromUrl(); + }) }); \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js b/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js new file mode 100644 index 0000000000000000000000000000000000000000..dd85243d662c9bf71e25212e89c42597e830c3d9 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/assets/js/uploadUnstructured.js @@ -0,0 +1,490 @@ +// initialize userId, userColors and targetId +var userId = randomUserId(); +var userColors = new Map(); +var userColorsDark = new Map(); +var targetId = 200; + +// declare document text +var documentText; + +/** + * This function will fire when the DOM is ready + */ +$(document).ready(function() { + + /** + * Context menu handler + */ + $.contextMenu({ + selector: '.context-menu-one', + callback: function(key, options) { + + // close context menu + window.close; + + // initialize selected body + var body = getSelectedTextFromTextArea(); + + // if user selected something + if (body.length > 0) { + // annotationPostRequest + var request = { + userId: userId, + targetId: targetId, + body: body, + startCharacter: window.getSelection().getRangeAt(0).startOffset, + endCharacter: window.getSelection().getRangeAt(0).endOffset + }; + + console.log(request); + + createAnnotation(request, function(response) { + // display the new annotation + displayAnnotation(response); + + }); + } + + }, + items: { + "annotation": {name: "Annotation", icon: "edit"} + } + }); + + $('#btnSave').click(function () { + location.href="project-student.jsp?token="+getUserTokenFromUrl(); + }); + + $('#btnBack').click(function () { + location.href="project-student.jsp?token="+getUserTokenFromUrl(); + }); + + documentText = $('#documentText').html(); + + // fetch annotations from server on page start + getAnnotations(targetId, function (response) { + // iterate over annotations and display each + $.each(response, function (i, annotation) { + displayAnnotation(annotation); + }) + }); + +}); + +/** + * POST: Save an annotation in the database + * + * @param annotationPostRequest The post request + * @param responseHandler The response handler + */ +function createAnnotation(annotationPostRequest, responseHandler) { + var url = "http://localhost:8080/rest/annotations/"; + var json = JSON.stringify(annotationPostRequest); + $.ajax({ + url: url, + type: "POST", + data: json, + contentType: "application/json", + dataType: "json", + success: function (response) { + responseHandler(response); + } + }); +} + +/** + * PATCH: Alter an annotation in database + * + * @param id The annotation id + * @param annotationPatchRequest The patch request + * @param responseHandler The response handler + */ +function alterAnnotation(id, annotationPatchRequest, responseHandler) { + var url = "http://localhost:8080/rest/annotations/" + id; + var json = JSON.stringify(annotationPatchRequest); + $.ajax({ + url: url, + type: "PATCH", + data: json, + contentType: "application/json", + dataType: "json", + success: function (response) { + responseHandler(response); + } + }); +} + +/** + * DELETE: Delete an annotation from database + * + * @param id The annotation id + */ +function deleteAnnotation(id) { + var url = "http://localhost:8080/rest/annotations/" + id; + $.ajax({ + url: url, + type: "DELETE", + dataType: "json", + success: function (response) { + // Nothing to do + } + }); +} + +/** + * GET: Get all annotations from database for a specific target + * + * + * @param targetId The target id + * @param responseHandler The response handler + */ +function getAnnotations(targetId, responseHandler) { + var url = "http://localhost:8080/rest/annotations/target/" + targetId; + $.ajax({ + url: url, + type: "GET", + dataType: "json", + success: function (response) { + // sort the responding annotations by timestamp (DESC) + response.sort(function (a, b) { + return a.timestamp - b.timestamp; + }); + // handle the response + responseHandler(response); + } + }); +} + +/** + * Delete annotation from list + * + * @param elem The parent li element + * @param id The id of the annotation + */ +function deleteUnstructuredAnnotationHandler(elem, id) { + // remove annotation from list + elem.remove() + // remove annotation from database + deleteAnnotation(id) +} + +/** + * Display annotation in the list + * + * @param annotation The annotation to be displayed + */ +function displayAnnotation(annotation) { + // fetch list of annotations + var list = $('#annotations') + + var deleteIcon = "fas fa-trash"; + var dateIcon = "fas fa-calendar"; + if (isTimestampToday(annotation.timestamp)) { + dateIcon = "fas fa-clock"; + } + + // insert annotation card + list.prepend( + $('<li>') + .attr('class', 'listelement') + .append( + $('<div>').attr('class', 'annotation-card') + .mouseenter(function () { + $(this).children('.annotation-header').css('background-color', getDarkUserColor(annotation.userId)); + }) + .mouseleave(function () { + $(this).children('.annotation-header').css('background-color', getUserColor(annotation.userId)); + }) + .append( + $('<div>').attr('class', 'annotation-header') + .css('background-color', getUserColor(annotation.userId)) + .append( + $('<div>').attr('class', 'annotation-header-title') + .append( + $('<div>').attr('class', 'overflow-hidden') + .append( + $('<i>').attr('class', 'fas fa-user') + ) + .append( + $('<span>').append(annotation.userId) + ) + ) + .append( + $('<div>').attr('class', 'overflow-hidden') + .append( + $('<i>').attr('class', 'fas fa-bookmark') + ) + .append( + $('<span>').append('title' + annotation.userId) + ) + ) + ) + .append( + $('<div>').attr('class', 'annotation-header-toggle') + .click(function () { + toggleButtonHandler($(this)); + }) + .append( + $('<i>').attr('class', 'fas fa-chevron-down') + ) + ) + ) + .append( + $('<div>').attr('class', 'annotation-body') + .append( + $('<p>').attr('class', 'overflow-hidden').append(annotation.body) + ) + ) + .append( + $('<div>').attr('class', 'annotation-footer') + .append( + function () { + if (userId == annotation.userId) { + return $('<div>').attr('class', 'annotation-footer-delete') + .append( + $('<i>').attr('class', deleteIcon) + ) + .click(function () { + deleteUnstructuredAnnotationHandler($(this).closest('li'), annotation.id) + }) + } + } + ) + .append( + $('<div>').attr('class', 'annotation-footer-date overflow-hidden') + .append( + $('<i>').attr('class', dateIcon) + ) + .append( + $('<span>').append(timestampToReadableTime(annotation.timestamp)) + ) + ) + + + ) + ) + .data('annotation', annotation) + .append(function () { + if ($('#annotations li').filter( ".listelement" ).length > 0) { + return $('<div>').attr('class', 'spacing') + } + }) + ); +} + +/** + * Add a highlighted text at specific position + * + * @param startCharacter The offset of the start character + * @param endCharacter The offset of the end character + * @param userId The user id + */ +function addHighlightedText(startCharacter, endCharacter, userId) { + // create <span> tag with the annotated text + var replacement = $('<span></span>').css('background-color', getUserColor(userId)).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(); + + // insert the replacementHtml + var newDocument = documentText.slice(0, startCharacter) + replacementHtml + documentText.slice(endCharacter); + + // set new document text + $('#documentText').html(newDocument); +} + +/** + * Restore the base text + */ +function deleteHighlightedText() { + $('#documentText').html(documentText); +} + +/** + * Get the text value of the selected text + * + * @returns {string} The text + */ +function getSelectedText() { + if(window.getSelection){ + return window.getSelection().toString(); + } + else if(document.getSelection){ + return document.getSelection(); + } + else if(document.selection){ + return document.selection.createRange().text; + } +} + +/** + * Get the text value of the selected text from a textarea + * + * @returns {string} The text + */ +function getSelectedTextFromTextArea() { + // if firefox + if( navigator.userAgent.toLowerCase().indexOf('firefox') > -1 ){ + // reference to the textarea + var txtarea = document.getElementById("upload-area"); + // get index of first character + var start = txtarea.selectionStart; + // get index of last character + var end = txtarea.selectionEnd; + // return substring from start to end + return txtarea.value.substring(start, end); + } + else if(window.getSelection){ + return window.getSelection().toString(); + } + else if(document.getSelection){ + return document.getSelection(); + } + else if(document.selection){ + return document.selection.createRange().text; + } +} + +/** + * Get color based on user id + * + * @param userId The id of the user + * @returns {string} The user color + */ +function getUserColor(userId) { + // insert new color if there is no userId key + if (userColors.get(userId) == null) { + generateRandomColor(userId); + } + // return the color + return userColors.get(userId); +} + +/** + * Get dark color based on user id + * + * @param userId The id of the user + * @returns {string} The dark user color + */ +function getDarkUserColor(userId) { + // insert new color if there is no userId key + if (userColorsDark.get(userId) == null) { + generateRandomColor(userId); + } + // return the color + return userColorsDark.get(userId); +} + +/** + * Generate a random color of the format 'rgb(r, g, b)' + * + * @param userId The given user id + */ +function generateRandomColor(userId) { + var r = Math.floor(Math.random()*56)+170; + var g = Math.floor(Math.random()*56)+170; + var b = Math.floor(Math.random()*56)+170; + var r_d = r - 50; + var g_d = g - 50; + var b_d = b - 50; + + var color = 'rgb(' + r + ',' + g + ',' + b + ')'; + var colorDark = 'rgb(' + r_d + ',' + g_d + ',' + b_d + ')'; + + userColors.set(userId, color); + userColorsDark.set(userId, colorDark); +} + +/** + * Calculate and build a readable timestamp from an unix timestamp + * + * @param timestamp A unix timestamp + * @returns {string} A readable timestamp + */ +function timestampToReadableTime(timestamp) { + // build Date object from timestamp + var annotationDate = new Date(timestamp); + // declare response + var responseTimestamp; + + // if annotation is from today + if (isTimestampToday(timestamp)) { + // get hours from date + var hours = annotationDate.getHours(); + // get minutes from date + var minutes = "0" + annotationDate.getMinutes(); + // get seconds from date + // var seconds = "0" + annotationDate.getSeconds(); + + // build readable timestamp + responseTimestamp = hours + ":" + minutes.substr(-2); + } + // else annotation is not from today + else { + // get date + var date = annotationDate.getDate(); + // get month + var month = annotationDate.getMonth(); + // get year + var year = annotationDate.getFullYear(); + + // build readable timestamp + responseTimestamp = date + "." + month + "." + year; + } + + return responseTimestamp; +} + +/** + * Check if given timestamp is from today + * + * @param timestamp The given timestamp in milliseconds + * @returns {boolean} Returns true if the timestamp is from today + */ +function isTimestampToday(timestamp) { + // now + var now = new Date(); + // build Date object from timestamp + var date = new Date(timestamp); + + // return true if timestamp is today + if (now.getDate() == date.getDate() && now.getMonth() == date.getMonth() && now.getFullYear() == date.getFullYear()) { + return true; + } + else { + return false; + } +} + +/** + * Toggle between the toggle button status + * + * @param element The given toggle button + */ +function toggleButtonHandler(element) { + // open and close annotation text + element.parent().siblings(".annotation-body").children("p").toggleClass("overflow-hidden"); + // toggle between up and down button + element.children("i").toggleClass("fa-chevron-down fa-chevron-up") +} + +function lockButtonHandler() { + var lock = $('#btnLock').children('i') + lock.toggleClass("fa-lock-open fa-lock") + + var area = $('#upload-area') + if (area.attr('readonly')) { + area.attr('readonly', false); + } + else { + area.attr('readonly', true); + } +} + +/* + MOCKUP FUNCTIONS + */ +function randomUserId() { + return Math.floor((Math.random() * 12) + 1);; +} + diff --git a/gemeinsamforschen/src/main/webapp/pages/createJournal.jsp b/gemeinsamforschen/src/main/webapp/pages/createJournal.jsp new file mode 100644 index 0000000000000000000000000000000000000000..1edabf9631499d60bb0966743de7bdcbecc6a19a --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/createJournal.jsp @@ -0,0 +1,104 @@ +<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Tagebucheintrag erstellen</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <link rel="stylesheet" href="../assets/css/styles.css"> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/inscrybmde@1.11.3/dist/inscrybmde.min.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/inscrybmde@1.11.3/dist/inscrybmde.min.js"></script> + <link rel="stylesheet" href="../assets/fonts/font-awesome.min.css"> + <link rel="stylesheet" href="../assets/css/Community-ChatComments.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu-1.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> + <link rel="stylesheet" type="text/css" href="../assets/css/create-journal.css"> + +</head> + +<body> +<div id="wrapper"> + <menu:menu></menu:menu> + + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1 id="projectId">project1 + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a></h1> + </div> + <div> + <table> + <tr> + <td id="yourContent"> + <h1> Tagebucheintrag erstellen </h1> + + <form id="journalform" class="form-journal" method="POST" action="../rest/journal/save" > + + <input type="hidden" name="student" value="0"> + <input type="hidden" name="project" value="0"> + + <div class="journal-form-container"> + + <div class = "journal-form-visibility"> + Sichtbarkeit: + <select id="visibility" name="visibility" form="journalform"> + <option value="ALL"> Alle </option> + <option value="GROUP"> Gruppe </option> + <option value="DOZENT"> Dozent </option> + <option value="NONE"> Nur Ich </option> + </select> + </div> + + <div class = "journal-form-category"> + Kategorie: + <select name="category" form="journalform"> + <option value="TITEL"> Titel </option> + <option value="RECHERCHE"> Recherche </option> + <option value="LITERATURVERZEICHNIS"> Literaturverzeichnis </option> + <option value="FORSCHUNGSFRAGE"> Forschungsfrage </option> + <option value="UNTERSUCHUNGSKONZEPT"> Untersuchungskonzept </option> + <option value="METHODIK"> Methodik </option> + <option value="DURCHFUEHRUNG"> Durchführung </option> + <option value="AUSWERTUNG"> Auswertung </option> + + </select> + </div> + + + <div class ="journal-form-editor"> + <textarea id = "editor" name="text" form="journalform" > + </textarea> + </div> + + <div class="journal-form-buttons"> + <input class="btn btn-default btn-sm" type="submit"> + <a class="btn btn-default btn-sm" href="eportfolio.jsp?token=test"> Zurück </a> + </div> + + </div> + </form> + + </td> + </tr> + </table> + </div> + </div> +</div> + +<script src="../assets/js/jquery.min.js"></script> +<script src="../assets/bootstrap/js/bootstrap.min.js"></script> +<script src="../assets/js/Sidebar-Menu.js"></script> +<script src="../assets/js/createJournal.js"></script> +</body> + +</html> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/editDescription.jsp b/gemeinsamforschen/src/main/webapp/pages/editDescription.jsp new file mode 100644 index 0000000000000000000000000000000000000000..664220c7710c7890eb7d2ef947206ee27030e80a --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/editDescription.jsp @@ -0,0 +1,78 @@ +<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Tagebucheintrag erstellen</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <link rel="stylesheet" href="../assets/css/styles.css"> + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/inscrybmde@1.11.3/dist/inscrybmde.min.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/inscrybmde@1.11.3/dist/inscrybmde.min.js"></script> + <link rel="stylesheet" href="../assets/fonts/font-awesome.min.css"> + <link rel="stylesheet" href="../assets/css/Community-ChatComments.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu-1.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> + <link rel="stylesheet" type="text/css" href="../assets/css/editDescription.css"> + +</head> + +<body> +<div id="wrapper"> + <menu:menu></menu:menu> + + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1 id="projectId">project1 + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a></h1> + </div> + <div> + <table> + <tr> + <td id="yourContent"> + <h1> Projektbeschreibung bearbeiten </h1> + + <form id="descriptionform" class="form-journal" method="POST" action="../rest/projectdescription/saveText"> + + <input type="hidden" name="student" value="0"> + <input type="hidden" name="project" value="0"> + + <div class="description-form-container"> + + <div class ="description-form-editor"> + <textarea id = "editor" name="text" form="descriptionform" > + </textarea> + </div> + + <div class="description-form-buttons"> + <input class="btn btn-default btn-sm" type="submit"> + <a class="btn btn-default btn-sm" href="eportfolio.jsp?token=test">Zurück</a> + </div> + + </div> + </form> + + </td> + </tr> + </table> + </div> + </div> +</div> + +<script src="../assets/js/jquery.min.js"></script> +<script src="../assets/bootstrap/js/bootstrap.min.js"></script> +<script src="../assets/js/Sidebar-Menu.js"></script> +<script src="../assets/js/editDescription.js"></script> +</body> + +</html> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/eportfolio.jsp b/gemeinsamforschen/src/main/webapp/pages/eportfolio.jsp new file mode 100644 index 0000000000000000000000000000000000000000..08e452126196eb62a4588ecf857858073fef91bc --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/eportfolio.jsp @@ -0,0 +1,165 @@ +<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>E-Portfolio</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <link rel="stylesheet" href="../assets/css/styles.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <link rel="stylesheet" href="../assets/fonts/font-awesome.min.css"> + <link rel="stylesheet" href="../assets/css/Community-ChatComments.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu-1.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> + <link rel="stylesheet" href="../assets/css/e-portfolio.css"> +</head> + +<body> +<div id="wrapper"> + <menu:menu></menu:menu> + + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1 id="projectId">project1 + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a></h1> + </div> + <div> + <table> + <tr> + <td id="yourContent"> + + <h1>E-Portfolio</h1> + + <ul class="nav nav-tabs"> + <li class="active"><a data-toggle="tab" href="#description">Beschreibung</a></li> + <li><a data-toggle="tab" href="#journal-container">Lerntagebuch</a></li> + </ul> + <div class="tab-content"> + + <div id = "description" class="tab-pane fade in active "> + <div class="journal-description-container"> + <div class="journal-description-title"> + </div> + <div class="journal-description-edit" align="right"> + <a class="btn btn-default btn-sm" href="editDescription.jsp?project=0&token=test"> + <i class="fa fa-pencil"></i> Bearbeiten</a> + <a class="btn btn-default btn-sm" data-toggle="modal" data-target="#closeDescriptionModal"><i class="fa fa-check-square" aria-hidden="true"></i>Abschließen</a> + + </div> + <div class="journal-description-text"> + </div> + <div class="journal-description-group"> + <h3>Gruppe</h3> + </div> + <div class="journal-description-links"> + <h3>Links</h3> + + </div> + + </div> + </div> + + <div id="journal-container" class="tab-pane fade"> + <h2>Lernatagebuch</h2> + <div class="input-group"> + <select id="journalfilter" class="form-control" style="width:auto;" onchange="filterJournals()"> + <option value="ALL">Alle</option> + <option value="OWN">Eigene</option> + </select> + + <a class="btn btn-default btn-sm" href="createJournal.jsp?token=test">Neu</a> + </div> + <div class="journal"> + </div> + </div> + </div> + </td> + </tr> + </table> + </div> + </div> +</div> + +<div class="modal fade" id="addLinkModal" role="dialog"> + <div class="modal-dialog modal-sm"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal">×</button> + <h4 class="modal-title">Link hinzufügen</h4> + </div> + <div class="modal-body"> + <form id="linkform" method="POST" action="../rest/projectdescription/addLink" > + Name:<br> + <input type="text" name="name" form="linkform"> + <br> + URL:<br> + <input type="text" name="link" form="linkform"> + <br><br> + <input class="btn btn-default" type="submit" > + <button type="button" class="btn btn-default" data-dismiss="modal">Abbrechen</button> + </form> + </div> + </div> + </div> +</div> + + +<div class="modal fade" id="closeJournalModal" role="dialog"> + <div class="modal-dialog modal-sm"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal">×</button> + <h4 class="modal-title">Tagebucheintrag schließen</h4> + </div> + <div class="modal-body"> + Tagebucheintrag schließen? Dieser Eintrag kann nach Bestätigung nicht mehr bearbeitet werden. + </div> + <div class="modal-footer"> + <div class="btn-group"> + <button type="button" class="btn btn-primary mr-auto">Ja</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Nein</button> + + </div> + </div> + </div> + </div> +</div> + +<div class="modal fade" id="closeDescriptionModal" role="dialog"> + <div class="modal-dialog modal-sm"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal">×</button> + <h4 class="modal-title">Beschreibung schließen</h4> + </div> + <div class="modal-body"> + Beschreibung schließen? Die Projektbeschreibung kann nach Bestätigung nicht mehr bearbeitet werden. + </div> + <div class="modal-footer"> + <div class="btn-group"> + <button type="button" class="btn btn-primary mr-auto" data-dismiss="modal">Ja</button> + <button type="button" class="btn btn-secondary" data-dismiss="modal">Nein</button> + + </div> + </div> + </div> + </div> +</div> + +<script src="../assets/js/jquery.min.js"></script> +<script src="../assets/bootstrap/js/bootstrap.min.js"></script> +<script src="../assets/js/Sidebar-Menu.js"></script> +<script src="../assets/js/e-portfolio.js"></script> +</body> + +</html> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/profile.jsp b/gemeinsamforschen/src/main/webapp/pages/profile.jsp new file mode 100644 index 0000000000000000000000000000000000000000..7f37281156d4d10c858001fff953e5d9c5aa6b29 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/profile.jsp @@ -0,0 +1,135 @@ +<%@ page import="unipotsdam.gf.core.management.ManagementImpl" %> +<%@ page import="unipotsdam.gf.core.management.user.User" %> +<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Profil</title> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <link rel="stylesheet" href="../assets/css/styles.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <link rel="stylesheet" href="../assets/fonts/font-awesome.min.css"> + <link rel="stylesheet" href="../assets/css/Community-ChatComments.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu-1.css"> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> +</head> + + +<% + // Retrieve user to be used here + String token = request.getParameter("token"); + ManagementImpl management = new ManagementImpl(); + User user = management.getUserByToken(token); +%> + +<body> +<div id="wrapper"> + <menu:menu></menu:menu> + + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1 id="projectId"> + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a></h1> + </div> + <div id="content"> + + <div class="page-header text-center"> + <h1>Mein Profil</h1> + </div> + + <div class="container"> + <div class="row"> + <%-- about --%> + <div class="col-sm-4"> + <h3>Über mich</h3> + <%-- TODO: retrieve profile data --%> + <ul class="list-group"> + <li class="list-group-item"> + <p>Name: <%=user.getName()%></p> + </li> + <li class="list-group-item"> + <p>Sonstiges:</p> + </li> + </ul> + + </div> + + <%-- activites --%> + <div class="col-sm-4"> + <h3>Aktivität</h3> + <%-- TODO: Retrieve achievements from database--%> + <ul class="list-group"> + <li class="list-group-item"> + <p> + Forschungsfrage erstellt + <a href="#"> + <span class="glyphicon glyphicon-link"></span> + </a> + </p> + </li> + <li class="list-group-item"> + <p> + Quiz "Goethe" erstellt + <a href="#"> + <span class="glyphicon glyphicon-link"></span> + </a> + </p> + </li> + <li class="list-group-item"> + <p> + Quiz "Schiller-Test" bearbeitet (3/5) + <a href="#"> + <span class="glyphicon glyphicon-link"></span> + </a> + </p> + </li> + <li class="list-group-item"> + <p> + Günther reviewed + <a href="#"> + <span class="glyphicon glyphicon-link"></span> + </a> + </p> + </li> + </ul> + </div> + + <%-- achievements --%> + <div class="col-sm-4"> + <h3>Erfolge</h3> + <%-- TODO: get achievements --%> + + <ul class="list-group"> + <li class="list-group-item"> + Quiz "Thermodynamik" ohne Fehler absolviert + </li> + <li class="list-group-item"> + Dossier vollständig hochgeladen + </li> + </ul> + </div> + </div> + </div> + + </div> + </div> +</div> + +<script src="../assets/js/jquery.min.js"></script> +<script src="../assets/bootstrap/js/bootstrap.min.js"></script> +<script src="../assets/js/Sidebar-Menu.js"></script> + +</body> + +</html> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/project-student.jsp b/gemeinsamforschen/src/main/webapp/pages/project-student.jsp index 5e04db86418a93cc02d7a2ba0638316429492249..99969f2b225d63cb6dddda7a23552eb02b5cc96b 100644 --- a/gemeinsamforschen/src/main/webapp/pages/project-student.jsp +++ b/gemeinsamforschen/src/main/webapp/pages/project-student.jsp @@ -213,6 +213,7 @@ </div> </div> <button id="nextPhase" class="btn btn-light">nächste Phase</button> + <button id="btnUnstructuredUpload" class="btn btn-light">Unstrukturierte Abgabe</button> </div> </footer> </div> diff --git a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html new file mode 100644 index 0000000000000000000000000000000000000000..092ea377d8a07edd36cb249bbf8fb6d665072304 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>muster-gemeinsam-forschen</title> + + <!-- css - annotationStyle --> + <link rel="stylesheet" type="text/css" href="../assets/css/upload-unstructured.css"> + <!-- css - contextMenu --> + <link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" /> + <!-- css - bootstrap --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <!-- css - styles --> + <link rel="stylesheet" href="../assets/css/styles.css"> + <!-- css - font awesome --> + <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous"> + <!-- css - sidebar --> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> + + <!-- js - jQuery --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <!-- js - bootstrap --> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <!-- js - jQuery ui position --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script> + <!-- js - contextMenu script --> + <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script> + <!-- js - annotationScript --> + <script src="../assets/js/uploadUnstructured.js"></script> + +</head> + +<body> +<div id="wrapper"> + <div id="sidebar-wrapper"> + <ul class="sidebar-nav"> + <li class="sidebar-brand"><a href="#">overview</a></li> + <li><a href="#">Quizfrage</a></li> + <li><a href="#">ePortfolio</a></li> + <li><a href="#">Beitrag</a></li> + <li><a href="#">Bewertung</a></li> + <li><a href="#">Logout</a></li> + </ul> + </div> + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1>Unstrukturierte Abgabe + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a> + </h1> + <div class="mainpage"> + <div class="leftcolumn"> + <div class="leftcontent "> + <div class="context-menu-one form-group" id="documentText"> + <label for="upload-area">Texteingabe:</label> + <textarea class="unstructured-textarea form-control" rows="20" id="upload-area"> +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + +Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + +Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + +Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + +At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + </textarea> + </div> + <div class="document-text-buttons"> + <button onclick="lockButtonHandler()" type="button" class="btn btn-secondary document-text-buttons-lock" id="btnLock"><i class="fas fa-lock-open" id="lock"></i></button> + <button type="button" class="btn btn-secondary document-text-buttons-save" id="btnSave">Speichern</i></button> + </div> + </div> + </div> + <div class="rightcolumn"> + <div class="rightcontent"> + <ol id="annotations"> + </ol> + </div> + </div> + </div> + </div> + </div> +</div> +</body> + +</html> \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp new file mode 100644 index 0000000000000000000000000000000000000000..98dba6d3b364f74390ee3854c86089c0fec1f224 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/pages/upload-unstructured.jsp @@ -0,0 +1,90 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib uri="../core/pages/gemeinsamForschen.tld" prefix="menu"%> + +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>muster-gemeinsam-forschen</title> + + <!-- css - annotationStyle --> + <link rel="stylesheet" type="text/css" href="../assets/css/upload-unstructured.css"> + <!-- css - contextMenu --> + <link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" /> + <!-- css - bootstrap --> + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> + <!-- css - styles --> + <link rel="stylesheet" href="../assets/css/styles.css"> + <!-- css - font awesome --> + <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous"> + <!-- css - sidebar --> + <link rel="stylesheet" href="../assets/css/Sidebar-Menu.css"> + + <!-- js - jQuery --> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> + <!-- js - bootstrap --> + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> + <!-- js - jQuery ui position --> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" type="text/javascript"></script> + <!-- js - contextMenu script --> + <script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script> + <!-- js - utility script --> + <script src="../assets/js/utility.js"></script> + <!-- js - annotationScript --> + <script src="../assets/js/uploadUnstructured.js"></script> + +</head> + +<body> +<div id="wrapper"> + <menu:menu></menu:menu> + <div class="page-content-wrapper"> + <div class="container-fluid"> + <h1>Unstrukturierte Abgabe + <a href="#"> + <span class="glyphicon glyphicon-envelope" + style="font-size:27px;margin-top:-17px;margin-left:600px;"></span> + </a> + <a href="#"> + <span class="glyphicon glyphicon-cog" style="font-size:29px;margin-left:5px;margin-top:-25px;"></span> + </a> + </h1> + <div class="mainpage"> + <div class="leftcolumn"> + <div class="leftcontent "> + <div class="context-menu-one form-group" id="documentText"> + <label for="upload-area">Texteingabe:</label> + <textarea class="unstructured-textarea form-control" rows="20" id="upload-area"> +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + +Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. + +Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. + +Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. + +At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. + </textarea> + </div> + <div class="document-text-buttons"> + <button onclick="lockButtonHandler()" type="button" class="btn btn-secondary document-text-buttons-lock" id="btnLock"><i class="fas fa-lock-open" id="lock"></i></button> + <button type="button" class="btn btn-secondary document-text-buttons-back" id="btnBack">Zurück</button> + <button type="button" class="btn btn-primary document-text-buttons-save" id="btnSave">Speichern</button> + </div> + </div> + </div> + <div class="rightcolumn"> + <div class="rightcontent"> + <ol id="annotations"> + </ol> + </div> + </div> + </div> + </div> + </div> +</div> +</body> + +</html> \ No newline at end of file