diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index cdf36c186..cd076ccb4 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -56,22 +56,45 @@ Add a slot, named "CS2113T" on the coming monday, from 0800hrs to 0900hrs with t This section displays the current implemented features as well as features that will be implemented in the future. +[NOTE] +*For ease of communication, this document will refer to lessons/activities/events/appointments that you might add into the Planner as _slots_.* + ==== -*Command Format* -* Words in UPPER_CASE are the parameters to be supplied by the user. E.g. in `t/TAG`, `TAG` is a parameter which can be used as the name of the tag. -* Items in square brackets are optional. e.g in `add n/NAME [l/LOCATION]`, `LOCATION` is an optional parameter and is not required to successfully run the command. -* Items with `…` after them can be used multiple times including zero times e.g. `[t/TAG]…` can be used 0 times, or as `t/lab`, `t/lecture`, `t/tutorial` etc. -* Parameters can be in any order e.g. if the command specifies `st/START_TIME et/END_TIME d/DATE`, then both `et/09:00 st/08:00 d/2-13-2019` and `et/09:00 d/2-13-2019 st/08:00` are acceptable. +*Tagging System* + +Unlike other commercial calendar/scheduling/planner software, PlanMySem makes use of a tagging system to manage slots. + +Using tags to tag slots will make tasks easier for you in the future. Tasks such as viewing, deleting and editing slots will be more efficient and performed quicker. + +Recommended uses for tags: + +1. Tag modules. e.g. "CS2113T", "CS2101". +2. Tag type of lesson. e.g. "Lecture", "Tutorial", "Lab". +3. Tag type of activities. e.g. "Sports", "Seminar", "Talk" +4. Tag difficulty of task. e.g. "Tough", "Simple", "Trivial" + +*Recursion System* + +Recursion facilitate quick addition of multiple slots, similar to Microsoft Outlook's series of appointments. + +In NUS, academic semesters are split into weeks of several types. Recursion allows you to add slots to these types of weeks with ease through the use of the `r/` parameter. *Parameters* Parameters in _PlanMySem_ are designed to be, short and easy to memorise. Once you are familarised with them, they should be intuitive to use. The list of parameters below is useful for your reference as you jump right into grasping the system. +*Command Format* + +* Words in UPPER_CASE are the parameters to be supplied by the user. E.g. in `t/TAG`, `TAG` is a parameter which can be used as the name of the tag. +* Items in square brackets are optional. e.g in `add [l/LOCATION]`, `LOCATION` is a parameter that may be omited. +* Items with `…` after them can be used multiple times including zero times e.g. `[t/TAG]…` can be used as (i.e. 0 times), `t/lab`, `t/lecture`, `t/tutorial` etc. +* Parameters can be in any order e.g. if the command specifies `st/START_TIME et/END_TIME d/DATE`, then both `et/09:00 st/08:00 d/2-13-2019` and `et/09:00 d/2-13-2019 st/08:00` is also acceptable. + [horizontal] *Parameter*:: *Description* -`n/`:: *Name of an activity _slot_.* +`n/`:: *Name of a _slot_.* `d/`:: *Date / Day of week.* + Format: + * Dates: `01-01`, `2019-01-02` @@ -85,7 +108,7 @@ The list of parameters below is useful for your reference as you jump right into * 24-Hour in the form of “hh:mm”. e.g. `23:00` * 12-Hour in the form of `hh:mm+AM|PM`. e.g. `12:30 AM` * Duration of the event in minutes. e.g. `60` represents 60 minutes -`r/`:: *Specify recurrence of an activity _slot_.* + +`r/`:: *Specify recurrence of a _slot_.* + Format: + * Select normal weeks: `normal` * Select recess week: `recess` @@ -95,7 +118,7 @@ The list of parameters below is useful for your reference as you jump right into `l/`:: *Location.* `des/`:: *Description.* `t/`:: *Tag.* -`nn/`:: *New name of an activity _slot_.* +`nn/`:: *New name of a _slot_.* `nd/`:: *New Date.* `nst/`:: *New Start Time.* `net/`:: *New End Time.* diff --git a/src/planmysem/commands/AddCommand.java b/src/planmysem/commands/AddCommand.java index 3dfe6b798..16ecd0829 100644 --- a/src/planmysem/commands/AddCommand.java +++ b/src/planmysem/commands/AddCommand.java @@ -2,9 +2,9 @@ import java.time.LocalDate; import java.time.LocalTime; -import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import planmysem.common.Utils; import planmysem.data.exception.IllegalValueException; @@ -65,7 +65,7 @@ public AddCommand(int day, String name, String location, String description, Loc @Override public CommandResult execute() { Set dates = recurrence.generateDates(planner.getSemester()); - HashMap days = new HashMap<>(); + Map days = new TreeMap<>(); for (LocalDate date : dates) { try { @@ -86,17 +86,21 @@ public CommandResult execute() { /** * Craft success message. */ - public static String craftSuccessMessage(HashMap days, Slot slot) { + public static String craftSuccessMessage(Map days, Slot slot) { StringBuilder sb = new StringBuilder(); sb.append("On dates:"); + int count = 1; for (Map.Entry day : days.entrySet()) { - sb.append("\n\t"); + sb.append("\n"); + sb.append(count); + sb.append(".\t"); sb.append(day.getValue().getType()); sb.append(", "); sb.append(day.getKey().toString()); sb.append(", "); sb.append(day.getKey().getDayOfWeek().toString()); + count++; } sb.append("\n\n"); diff --git a/src/planmysem/commands/Command.java b/src/planmysem/commands/Command.java index c8f0fd426..97753947d 100644 --- a/src/planmysem/commands/Command.java +++ b/src/planmysem/commands/Command.java @@ -58,6 +58,15 @@ public void setData(Planner planner, List getTargetSlot() throws IndexOutOfBoundsException { return relevantSlots.get(targetIndex - DISPLAYED_INDEX_OFFSET); } - - public int getTargetIndex() { - return targetIndex; - } - - public void setTargetIndex(int targetIndex) { - this.targetIndex = targetIndex; - } } diff --git a/src/planmysem/commands/DeleteCommand.java b/src/planmysem/commands/DeleteCommand.java index 22c8a1a8f..025ad5ac5 100644 --- a/src/planmysem/commands/DeleteCommand.java +++ b/src/planmysem/commands/DeleteCommand.java @@ -70,7 +70,8 @@ public CommandResult execute() { } } if (selectedSlots.size() == 0) { - return new CommandResult(String.format(MESSAGE_SUCCESS_NO_CHANGE, craftSelectedMessage())); + return new CommandResult(String.format(MESSAGE_SUCCESS_NO_CHANGE, + Messages.craftSelectedMessage(tags))); } } else { try { @@ -88,11 +89,11 @@ public CommandResult execute() { // perform deletion of slots from the planner for (Map.Entry slot: selectedSlots.entrySet()) { - planner.getSemester().getDays().get(slot.getKey().toLocalDate()).removeSlot(slot.getValue()); + planner.getSemester().removeSlot(slot.getKey().toLocalDate(), slot.getValue()); } return new CommandResult(String.format(MESSAGE_SUCCESS, selectedSlots.size(), - craftSelectedMessage(), craftSuccessMessage(selectedSlots))); + Messages.craftSelectedMessage(tags), craftSuccessMessage(selectedSlots))); } /** @@ -106,12 +107,10 @@ private String craftSuccessMessage(Map selectedSlot int count = 1; for (Map.Entry editedSlot : selectedSlots.entrySet()) { - sb.append("\tItem: "); sb.append(count); - sb.append(": "); - sb.append("\n\t\t"); + sb.append(".\t"); sb.append(editedSlot.getValue().getName().toString()); - sb.append("\n\t\t"); + sb.append(", "); sb.append(editedSlot.getKey().toLocalDate().toString()); sb.append(" "); sb.append(editedSlot.getKey().toLocalTime().toString()); @@ -120,25 +119,10 @@ private String craftSuccessMessage(Map selectedSlot sb.append(", "); sb.append(editedSlot.getKey().getDayOfWeek().toString()); count++; - sb.append("\n\n"); - } - - return sb.toString(); - } - - /** - * Craft selected message. - */ - private String craftSelectedMessage() { - StringBuilder sb = new StringBuilder(); - sb.append("Selected Slots containing tags: \n"); - - for (Tag tag : tags) { - sb.append("\t"); - sb.append(tag.toString()); sb.append("\n"); } return sb.toString(); } + } diff --git a/src/planmysem/commands/EditCommand.java b/src/planmysem/commands/EditCommand.java index 9b7c43010..8ac80eea6 100644 --- a/src/planmysem/commands/EditCommand.java +++ b/src/planmysem/commands/EditCommand.java @@ -103,7 +103,8 @@ public CommandResult execute() { } } if (selectedSlots.size() == 0) { - return new CommandResult(String.format(MESSAGE_SUCCESS_NO_CHANGE, craftSelectedMessage())); + return new CommandResult(String.format(MESSAGE_SUCCESS_NO_CHANGE, + Messages.craftSelectedMessage(tags))); } } else { try { @@ -130,7 +131,7 @@ public CommandResult execute() { } return new CommandResult(String.format(MESSAGE_SUCCESS, selectedSlots.size(), - craftSelectedMessage(), craftSuccessMessage(selectedSlots))); + Messages.craftSelectedMessage(tags), craftSuccessMessage(selectedSlots))); } /** @@ -142,19 +143,19 @@ private String craftSuccessMessage(Map selectedSlot sb.append("Details Edited: "); if (startTime != null) { - sb.append("\n\tStart Time: "); + sb.append("\nStart Time: "); sb.append("\""); sb.append(startTime.toString()); sb.append("\""); } if (duration != -1) { - sb.append("\n\tDuration: "); + sb.append("\nDuration: "); sb.append("\""); sb.append(duration); sb.append("\""); } if (location != null) { - sb.append("\n\tLocation: "); + sb.append("\nLocation: "); sb.append("\""); if ("".equals(location)) { sb.append("null"); @@ -164,7 +165,7 @@ private String craftSuccessMessage(Map selectedSlot sb.append("\""); } if (description != null) { - sb.append("\n\tDescription: "); + sb.append("\nDescription: "); sb.append("\""); if ("".equals(description)) { sb.append("null"); @@ -178,14 +179,23 @@ private String craftSuccessMessage(Map selectedSlot sb.append("Edited Slots: "); sb.append("\n"); + sb.append(craftSelectedMessage(selectedSlots)); + + return sb.toString(); + } + + /** + * Craft success message. + */ + private String craftSelectedMessage(Map selectedSlots) { + StringBuilder sb = new StringBuilder(); + int count = 1; for (Map.Entry editedSlot : selectedSlots.entrySet()) { - sb.append("\tItem: "); sb.append(count); - sb.append(": "); - sb.append("\n\t\t"); + sb.append(".\t"); sb.append(editedSlot.getValue().getName().toString()); - sb.append("\n\t\t"); + sb.append(", "); sb.append(editedSlot.getKey().toLocalDate().toString()); sb.append(" "); sb.append(editedSlot.getKey().toLocalTime().toString()); @@ -194,22 +204,6 @@ private String craftSuccessMessage(Map selectedSlot sb.append(", "); sb.append(editedSlot.getKey().getDayOfWeek().toString()); count++; - sb.append("\n\n"); - } - - return sb.toString(); - } - - /** - * Craft selected message. - */ - private String craftSelectedMessage() { - StringBuilder sb = new StringBuilder(); - sb.append("Selected Slots containing tags: \n"); - - for (Tag tag : tags) { - sb.append("\t"); - sb.append(tag.toString()); sb.append("\n"); } diff --git a/src/planmysem/commands/FindCommand.java b/src/planmysem/commands/FindCommand.java index 3cd016ff0..634cf957c 100644 --- a/src/planmysem/commands/FindCommand.java +++ b/src/planmysem/commands/FindCommand.java @@ -7,7 +7,6 @@ import java.util.regex.Pattern; import javafx.util.Pair; - import planmysem.data.semester.Day; import planmysem.data.slot.ReadOnlySlot; import planmysem.data.slot.Slot; @@ -21,8 +20,8 @@ public class FindCommand extends Command { public static final String COMMAND_WORD = "find"; public static final String COMMAND_WORD_SHORT = "f"; - public static final String MESSAGE_SUCCESS = "%1$s Slots listed.\n%2$s"; - public static final String MESSAGE_SUCCESS_NONE = "0 Slots listed.\n"; + private static final String MESSAGE_SUCCESS = "%1$s Slots listed.\n%2$s"; + private static final String MESSAGE_SUCCESS_NONE = "0 Slots listed.\n"; public static final String MESSAGE_USAGE = COMMAND_WORD + ":\n" + "Finds all slots whose name " + "contains the specified keywords (not case-sensitive).\n\t" @@ -46,7 +45,6 @@ public CommandResult execute() { matchedSlots.add(slots); date = entry.getKey(); relevantSlots.add(new Pair<>(date, slots)); - } } } diff --git a/src/planmysem/common/Messages.java b/src/planmysem/common/Messages.java index 1882aa075..cd9046f37 100644 --- a/src/planmysem/common/Messages.java +++ b/src/planmysem/common/Messages.java @@ -1,5 +1,9 @@ package planmysem.common; +import java.util.Set; + +import planmysem.data.tag.Tag; + /** * Container for user visible messages. */ @@ -27,4 +31,26 @@ public class Messages { + "\n\t24-Hour in the form of “hh:mm”. e.g. \"23:00\"" + "\n\t12-Hour in the form of `hh:mm+AM|PM`. e.g. \"12:30am\"" + "\n\tOr perhaps type a duration in minutes. e.g. \"60\" to represent 60 minutes"; + + + /** + * Craft selected message. + */ + public static String craftSelectedMessage(Set tags) { + StringBuilder sb = new StringBuilder(); + sb.append("Selected Slots containing tags: \n"); + + int count = 1; + for (Tag tag : tags) { + sb.append(count); + sb.append(".\t"); + sb.append(tag.toString()); + sb.append("\n"); + count++; + } + + return sb.toString(); + } + + } diff --git a/src/planmysem/data/semester/Semester.java b/src/planmysem/data/semester/Semester.java index d5296a10b..dd1565747 100644 --- a/src/planmysem/data/semester/Semester.java +++ b/src/planmysem/data/semester/Semester.java @@ -105,6 +105,13 @@ public Day addSlot(LocalDate date, Slot slot) throws DateNotFoundException { return days.get(date); } + /** + * Removes a Slot to the Semester. + */ + public void removeSlot(LocalDate date, ReadOnlySlot slot) { + days.get(date).removeSlot(slot); + } + /** * Edits a Slot in the Semester. * diff --git a/src/planmysem/data/slot/ReadOnlySlot.java b/src/planmysem/data/slot/ReadOnlySlot.java index 1409b7ee7..6e27781ac 100644 --- a/src/planmysem/data/slot/ReadOnlySlot.java +++ b/src/planmysem/data/slot/ReadOnlySlot.java @@ -46,28 +46,34 @@ default String getAsTextShowAll() { sb.append("Slot Details:"); - sb.append("\n\tName: "); + sb.append("\nName: "); sb.append(getName()); - sb.append("\n\tLocation: "); + sb.append("\nLocation: "); sb.append(getLocation()); - sb.append("\n\tDescription: "); + sb.append("\nDescription: "); sb.append(getDescription()); - sb.append("\n\tTime: "); + sb.append("\nTime: "); sb.append(getStartTime()); sb.append(" to "); sb.append(Utils.getEndTime(getStartTime(), getDuration())); - sb.append("\n\tDuration: "); + sb.append("\nDuration: "); sb.append(getDuration()); - sb.append("\n\tTags: "); + sb.append("\nTags: "); + + int count = 1; for (Tag tag : getTags()) { - sb.append("\n\t\t"); + sb.append("\n"); + sb.append("\t"); + sb.append(count); + sb.append(".\t"); sb.append(tag.toString()); + count++; } return sb.toString(); } diff --git a/test/java/planmysem/logic/LogicTest.java b/test/java/planmysem/logic/LogicTest.java index d9c2995e5..d1c19631e 100644 --- a/test/java/planmysem/logic/LogicTest.java +++ b/test/java/planmysem/logic/LogicTest.java @@ -167,6 +167,28 @@ public void execute_edit_invalidArgsFormat() throws Exception { "e nl/COM2 04-01", expectedMessage); } + // @Test + // public void execute_delete_successful() throws Exception { + // // setup expectations + // TestDataHelper helper = new TestDataHelper(); + // Slot slotToBeAdded = helper.slotOne(); + // LocalDate dateToBeAdded = LocalDate.now(); + // HashMap days = new HashMap<>(); + // days.put(dateToBeAdded, planner.getSemester().getDays().get(dateToBeAdded)); + // + // Planner expectedPlanner = new Planner(); + // expectedPlanner.addSlot(dateToBeAdded, slotToBeAdded); + // expectedPlanner.getSemester().removeSlot(dateToBeAdded, slotToBeAdded); + // planner.addSlot(dateToBeAdded, slotToBeAdded); + // + // // execute command and verify result + // assertCommandBehavior(helper.generateAddCommand(dateToBeAdded, slotToBeAdded), + // String.format(AddCommand.MESSAGE_SUCCESS, 1, AddCommand.craftSuccessMessage(days, slotToBeAdded)), + // expectedPlanner, + // false, + // Collections.emptyList()); + // } + /** * Test delete command */