diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c6d0de35e63..529c7a309af 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -8,6 +8,7 @@ pageNav: 3 + -------------------------------------------------------------------------------------------------------------------- ## **1. Introduction** @@ -187,15 +188,13 @@ The `add` feature is facilitated by a number of classes such as `Person` and `Mo Step 1. The user launches the application for the first time. -Step 2. The user executes `“add n/John Doe p/98765432 e/johnd@example.com g/CS2103T”` command to add a new person. `LogicManager#execute` is called which then calls `AddressBookParser#parseCommand` to decide on the type of command. `AddressBookParse`r` then calls `AddCommandParser`, +Step 2. The user executes `“add n/John Doe p/98765432 e/johnd@example.com g/CS2103T”` command to add a new person. -Step 3, The `AddCommandParser` is called to read the user input. `AddCommandParser` calls `ArgumentTokenizer#tokenize` to check the prefixes of the user input. `AddCommandParser` then calls `ArgumentMultimap#getValue()` to get inputs after each prefix. -The result of it is then passed to `ParserUtil#parse` methods to parse each attributes such as `Name`. `AddCommandParser` then makes new person object. `AddCommandParser` then calls `AddCommand` and passes `Person` inside. +Step 3, The `AddCommandParser` is called to read the user input. `AddCommandParser` parses the input and calls `AddCommand`. -Step.4 `AddCommand` then calls `Model#addPerson()` which then calls `AddressBook#addPerson()`. The latter method will add person inside the `uniquePersonList` in `addressBook`. `AddCommand` also calls `Model#addGroup` which then calls `AddressBook#addGroup` to add the group inside `grouplist` if the group does not exist. -Lastly, `AddCommand` adds the person inside the group +Step.4 `AddCommand` then calls `Model#addPerson()` which then calls `AddressBook#addPerson()`. The latter method will add person inside the `uniquePersonList` in `addressBook`. `AddCommand` also calls `Model#addGroup` which then calls `AddressBook#addGroup` to add the group inside `grouplist` if the group does not exist. Lastly, `AddCommand` adds the person inside the group -Note: No duplication is allowed in addressbook for most of Person’s attribute (name, email and phone number.) +**Note** No duplication is allowed in `addressbook` for most of Person’s attribute (name, email and phone number.) The following sequence diagram describes the process of `add` command: @@ -209,37 +208,7 @@ The following sequence diagram describes the process of `add` command: * Cons: User input may get relatively longer. * **Alternative 2:** Allow user to add as many groups as required for each `add` Command * Pros: Conveniently adds a person into multiple group while creating a new contact at the same time. - * Cons: User input can get potentially very long, increasing the chance of invalid input, relatively harder to implement parser. - --------------------------------------------------------------------------------------------------------------------- -### Adding Time a Person - -#### Implementation - -The `addtime` feature is facilitated by a number of classes such as `Person`, `Model` and `TimeInterval` - -Step 1. User launches the application. - -Step 2. The user executes `“addtime n/Alex Yeoh t/mon 1200 - mon 1400 t/tue 1000 - wed 1600”` command to add time slots to the person, Alex Yeoh. `LogicManager#execute` is called which then calls `AddressBookParser#parseCommand` to decide on the type of command. `AddressBookParser` then calls `AddTimeCommandParser`, - -Step 3, The `AddTimeCommandParser` is called to read the user input. `AddTimeCommandParser` calls `ArgumentTokenizer#tokenize` to check the prefixes of the user input. `AddTimeCommandParser` then calls `ArgumentMultimap#getValue()` to get inputs after each unique single prefix and `ArgumentMultimap#getAllValues()` to get inputs from prefix that are used more than once. -The result of it is then passed to `ParserUtil#parse()` methods to parse each attributes such as `Name`. `AddTimeCommandParser` then calls `AddTimeCommand`. - -Step.4 `AddTimeCommand` then calls `Model#addTimeToPerson()` which then calls `AddressBook#addTimeToPerson()`. The latter method will add time to the person. - -The following sequence diagram describes the process of `addtime` command: - - -#### Design consideration: - -**Aspect: Handling group attribute in user input** - -* **Alternative 1 (Current Choice):** Allows user to add more than one time intervals in each `addtime` command. - * Pros: Conveniently adds a multiple time intervals into person. - * Cons: User input may get relatively longer, relatively harder to implement parser. -* **Alternative 2:** Allow user to only add single time interval in each `addtime` Command - * Pros: Conveniently adds a person into group while creating a new contact at the same time, relatively easier to implement parser. - * Cons: User input can get potentially very long, increasing the chance of invalid input. + * Cons: User input can get potentially very long, increasing the chance of invalid input, relatively harder to implement parser. The implementation of it will get more complex. -------------------------------------------------------------------------------------------------------------------- @@ -247,7 +216,7 @@ The following sequence diagram describes the process of `addtime` command: #### Proposed Implementation -The Add Group mechanism is facilitated by `Group`. It is stored internally as a `Group`. This operation is exposed in the `Model` interface as `Model#addGroup()`. +The Add Group mechanism is facilitated by `Group` class. This operation is exposed in the `Model` interface as `Model#addGroup()`. Given below is an example usage scenario and how the group creation mechanism behaves at each step. @@ -255,6 +224,8 @@ Given below is an example usage scenario and how the group creation mechanism be **Step 2:** The user executes `new g/GROUPNAME` to create a new group with the name GROUPNAME. `CreateGroupCommandParser` parses the GROUPNAME, ensuring the input is valid, and creates a `CreateGroupCommand`, which calls `Model#addGroup()`. The model retrieves the existing groupList from the addressBook and adds this new group to the groupList. +**Note:** ProjectPRO does not allow 2 groups of the same name to be added. The group name must also be alphanumerical and non empty. + The following activity diagram summarizes what happens when a user executes a new command: @@ -275,19 +246,23 @@ Below is a sequence diagram that summarizes how a user creates a new group: -------------------------------------------------------------------------------------------------------------------- -### Group Remark Feature +### Adding a Group Remark #### Implementation -The proposed group remark feature is facilitated by the `Group` class. It includes a `Group Remark` field and implements the `Group#setGroupRemark()` operation. This feature is exposed in the `Model` interface as `Model#addGroupRemark()`. +The Group Remark mechanism is facilitated by the `Group Remark` class, involving other classes like `Group`. It implements the following operation: + +* `Group#setGroupRemark()` — Sets the group's remark. + +This operation is exposed in the `Model` interface as `Model#addGroupRemark()`. Here's an example usage scenario and how the group remark mechanism behaves at each step: -**Step 1.** The user creates a group called `CS2103T`. The `Group` is initialized with an empty `groupRemark`. +**Step 1.** The user creates a group called "CS2103T". The group is initialized with an empty `groupRemark`. -**Step 2.** The user executes the `remark g/CS2103T r/Quiz tomorrow` command to add the remark "Quiz tomorrow" to the `CS2103T` group. The `GroupRemarkCommandParser` extracts the group and remark from the input and creates a `GroupRemarkCommand`, which calls `Model#addGroupRemark(groupName, groupRemark)`. The model retrieves the existing `CS2103T` group from the database and calls the group's `Group#setRemark(groupRemark)`, adding the `groupRemark` to the group. +**Step 2.** The user executes the `remark g/CS2103T r/Quiz tomorrow` command to add the remark "Quiz tomorrow" to the "CS2103T" group. The `GroupRemarkCommandParser` extracts the group and remark from the input and creates a `GroupRemarkCommand`, which calls `Model#addGroupRemark(groupName, groupRemark)`. The model retrieves the existing "CS2103T" group from the database and calls the group's `Group#setGroupRemark(groupRemark)`, setting the "Quiz tomorrow" as the `groupRemark` of the group. -**Note:** If the user wants to modify the group remark, they can execute the same command with the new remark. The existing remark will be deleted and overwritten, and the new remark is stored in the group. +**Note:** If the user wants to modify the group remark, they can execute the same command with the new remark. The existing remark will be overwritten, and the new remark is stored in the group. The following activity diagram summarizes what happens when a user executes a new command: @@ -301,14 +276,17 @@ The following activity diagram summarizes what happens when a user executes a ne #### Design Considerations -**Aspects:** +**Aspects: How to change the group remark** -- **Alternative 1 (current choice):** Overrides original remark - - Pros: Easy to implement. - - Cons: May be troublesome if the user wants to keep contents from the original remark. -- **Alternative 2:** Edits original remark - - Pros: Easy to add more information. - - Cons: Could be confusing to edit if there are many changes or remark is too long. +- **Alternative 1 (current choice):** Override the original remark + - Pros: Easy to implement. + - Cons: May be troublesome if the user wants to keep contents from the original remark. + +- **Alternative 2:** Edit the original remark + - Pros: Easy to add more information. + - Cons: May be confusing to edit if there are many changes or remark is too long. + +-------------------------------------------------------------------------------------------------------------------- ### Delete Time Feature @@ -318,7 +296,7 @@ The proposed delete time feature is facilitated by the `timeIntervalList` and `P Step 1. The user launches the application. The `AddressBook` will be initialized with the free time of its contacts. -Step 2. The user executes the command `deleteTime n/Alex Yeoh t/mon 1200 - mon 1400 ;tue 1000 - wed 1600`. The `deleteTimeCommandParser` will be called to parse the inputs and call the `deletePersonTimeCommand`. The `deletePersonTime` command calls `Model#deleteTimeFromPerson()`, which will call `Person#deleteFreeTime()`. +Step 2. The user executes the command `deleteTime n/Alex Yeoh t/mon 1200 - mon 1400 t/tue 1000 - wed 1600`. The `deleteTimeCommandParser` will be called to parse the inputs and call the `deletePersonTimeCommand`. The `deletePersonTime` command calls `Model#deleteTimeFromPerson()`, which will call `Person#deleteFreeTime()`. **Note:** Since multiple inputs are allowed, an array list of time intervals are passed around, each of which is to be deleted. @@ -374,9 +352,9 @@ Below is an activity diagram that illustrates the control flow for Delete Person #### Implementation -The group remark mechanism is facilitated by `Group`. It is stored internally as a `Group Remark`. This operation is exposed in the `Model` interface as `Model#groupPerson(personName, groupName)`. +The group mechanism is facilitated by `Group`. It is stored internally as a `Group`. This operation is exposed in the `Model` interface as `Model#groupPerson(personName, groupName)`. -Given below is an example usage scenario and how the group remark mechanism behaves at each step. +Given below is an example usage scenario and how the group mechanism behaves at each step. **Step 1:** User launches the application. @@ -404,13 +382,13 @@ The following activity diagram summarizes what happens when a user executes a ne The List mechanism is facilitated by the `Model` class. -The operations they implement are exposed in the `Model` interface as `Model#updateFilteredPersonList(Predicate predicate)`. +The operation it utilises is exposed in the `Model` interface as `Model#updateFilteredPersonList(Predicate predicate)`. Given below is an example usage scenario and how the list mechanism behaves at each step. **Step 1:** User executes `list` command to view all contacts. After parsing, a new `ListCommand` object will be returned. -**Step 2:** `FindPersonCommand` is executed, in which `Model#updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS)` is called with the Predicate which will be true for all contacts. This updates the address book view, showing all the contacts in the address book to the user. +**Step 2:** `ListCommand` is executed, in which `Model#updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS)` is called with the Predicate which will be true for all contacts. This updates the address book view, showing all the contacts in the address book to the user. The following activity diagram summarizes what happens when a user executes a list command: @@ -424,75 +402,225 @@ The following activity diagram summarizes what happens when a user executes a li -------------------------------------------------------------------------------------------------------------------- -### Find Person and Find Group features +### Listgroup #### Implementation -The Find person/group mechanisms are facilitated by the `Model` class. +The Listgroup mechanism is facilitated by the `Model` class. -The operations they implement are exposed in the `Model` interface as `Model#updateFilteredPersonList(Predicate predicate)`. +The operation it utilises is exposed in the `Model` interface as `Model#getFilteredGroupList()`. -Both `FindPersonCommand` and `FindGroupCommand` implement an abstract class `FindCommand`, which helps to encapsulate the similarities between these two commands. +Given below is an example usage scenario and how the listgroup mechanism behaves at each step. -Since both Find Person and Find Group commands utilise the same command word, the `FindCommandParser` will create either a `FindPersonCommand` or `FindGroupCommand` and return it as a `FindCommand` after parsing the user input. +**Step 1:** User executes `listgroup` command to view all groups in their contact list. After parsing, a new `ListGroupCommand` object will be returned. -The following activity diagram summarizes what happens when a user executes a find command: +**Step 2:** `ListGroupCommand` is executed, in which `Model#getFilteredGroupList()` is called, returning all the groups the user has in the contact list. - +**Step 3:** The group names of all the groups in the contact list are appended to a `String` which will be displayed to the user as a message in the output box. -### Find Person +The following activity diagram summarizes what happens when a user executes a listgroup command: -Given below is an example usage scenario and how the Find Person mechanism behaves at each step. + -Step 1. The user executes `find n/Alex John` command to find all contacts whose names contain either 'Alex' or 'John' in the address book. After parsing, a new `FindPersonCommand` object will be returned along with the corresponding `Predicate`. + -Step 2. `FindPersonCommand` is executed, in which `Model#updateFilteredPersonList()` is called with the Predicate. This through all the contacts in the address book, showing the updated list of contacts whose names start with 'Alex' or 'John' to the user. +**Note:** The lifeline for `ListGroupCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. + + + +-------------------------------------------------------------------------------------------------------------------- + +### Adding Time to a Person or Group + +#### Implementation + +The Add Time to person/group mechanisms are facilitated by the `TimeInterval` class, involving other classes like `Person` and `Group`. It implements the following operations: + +* `Person#addFreeTime()` — Adds the inputted time intervals to the person. +* `Group#addTime()` — Adds the inputted time intervals to the group. + +These operations are exposed in the `Model` interface as `Model#addTimeToPerson()`, `Model#addTimeToGroup()` respectively. + +The following activity diagram summarizes what happens when a user executes an add time command: + + + +### Adding Time to a Person + +Given below is an example usage scenario and how the Add Time to Person mechanism behaves at each step. + +Step 1. The user executes `addtime n/Alex Yeoh t/mon 1300 - mon 1400 t/tue 1300 - tue 1400` command to add the free time intervals of Monday 1 pm to 2 pm and Tuesday 1 pm to 2 pm to a person named "Alex Yeoh" in the contact list. The `AddTimeCommandParser` will be called to parse the inputs and check if any of the inputted times clash with each other. It will then call the `AddTimeCommand`. + +**Note:** Since multiple inputs are allowed, an array list of time intervals is passed around, each of which is to be added. + +Step 2. `AddTimeCommand` is executed, in which `Model#addTimeToPerson()` is called. -**Note:** If there are no contacts whose name contains 'Alex, or 'John', no contacts will be shown. +**Note:** If no such person named "Alex Yeoh" exists, a `CommandException` will be thrown. +Step 3. `Model#addTimeToPerson()` will also call `Person#addFreeTime()` which will add all times stored in the array list to the person's list of free times, given that none of the times clash with the person's existing free time intervals. If clashes do occur, the user will be notified of the problematic time intervals while the problem-free intervals will be added. -The following sequence diagram shows how the Find Person operation works: - +The following sequence diagram shows how the Add Time to Person operation works: + -**Note:** The lifeline for `FindPersonCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +**Note:** The lifeline for `AddTimeCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. -### Find Group +### Adding Time to a Group + +The Add Time to Group command mechanism behaves the same as the Add Time to Person command above, except it uses the `Group` class instead of the `Person` class. + +#### Design Considerations + +**Aspect: How to handle two similar but different commands (add meeting time to group and add free time to person)** + +* **Alternative 1 (current choice):** Use different command words for both commands + * Pros: Less confusing as the 2 commands add different types of times. + * Cons: Users have to remember more command words which may take more time to get used to. + +* **Alternative 2:** Use the same command word + * Pros: Reduces the amount of command words that users have to remember. + * Cons: Users may get confused because the 2 commands do not add the same types of times. + +**Aspect: How to handle time clashes** + +* **Alternative 1 (current choice):** Add all non-clashing time intervals + * Pros: More convenient as users will not need to retype the entire command if there is a clash. + * Cons: May no longer want to add certain non-clashing inputs after encountering this clash. + +* **Alternative 2:** Reject all time intervals + * Pros: Allows users to (heavily) edit their inputted time intervals accordingly to resolve clashes. + * Cons: May be troublesome to retype the entire command, especially if it is very long. + +-------------------------------------------------------------------------------------------------------------------- + +### Listing Time for a Person or Group + +#### Implementation + +The List Time for person/group mechanisms are facilitated by the `TimeInterval` class, involving other classes like `Person` and `Group`. It implements the following operations: + +* `Person#getTime()` — Shows the person's time intervals. +* `Group#getTime()` — Shows the group's time intervals. + +These operations are exposed in the `Model` interface as `Model#getTimeFromPerson()`, `Model#getTimeFromGroup()` respectively. + +Both `ListTimePersonCommand` and `ListTimeGroupCommand` implement an abstract class `ListTimeCommand`, which helps to encapsulate the similarities between these two commands. -The Find Group mechanism works like the Find Person mechanism, but it calls on an extra method `Group#getGroupRemark()`. +Since both List Time Person and List Time Group commands utilise the same command word `listtime`, the `ListTimeCommandParser` will create either a `ListTimePersonCommand` or `ListTimeGroupCommand` and return it as a `ListTimeCommand` after parsing the user input. -Given below is an example usage scenario and how the Find Group mechanism behaves at each step. +The following activity diagram summarizes what happens when a user executes an add time command: -Step 1. The user executes `find g/CS2100` command to find all contacts belonging in a group named 'CS2100' in the address book. After parsing, a new `FindGroupCommand` object will be returned along with the corresponding `Predicate`. + -Step 2. `FindGroupCommand` is executed, in which `Model#updateFilteredPersonList()` is called with the Predicate. This through all the contacts in the address book, showing the updated list of contacts who belong in the group 'CS2100'. +### Listing Time from a Person + +Given below is an example usage scenario and how the List Time from Person mechanism behaves at each step. + +Step 1. The user executes `listtime n/Alex Yeoh` command to list the free time intervals of a person named "Alex Yeoh" in the contact list. The `ListTimeCommandParser` will be called to parse the inputs. It will then call the `ListTimePersonCommand`. + +Step 2. `ListTimePersonCommand` is executed, in which `Model#getTimeFromPerson()` is called. -**Note:** If no such group named 'CS2100' exists, a `CommandException` will be thrown. +**Note:** If no such person named "Alex Yeoh" exists, a `CommandException` will be thrown. -Step 3. `Group#getGroupRemarks()` is called, and the previously saved group remarks is displayed to the user. +Step 3. `Model#getTimeFromPerson()` will also call `Person#getTime()` which will parse all times stored in the array list into an easy-to-read chunk using a StringBuilder, and show it in the output box. + +The following sequence diagram shows how the List Time from Person operation works: + + + + + +**Note:** The lifeline for `ListTimePersonCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. + + -The following sequence diagram shows how the Find Group operation works: +### Listing Time from a Group +The List Time from Group command mechanism behaves the same as the List Time from Person command above, except it uses the `Group` class instead of the `Person` class. +#### Design Considerations + +**Aspect: How to handle two similar but different commands (add meeting time to group and add free time to person)** + +* **Alternative 1 (current choice):** Use different command words for both commands + * Pros: Less confusing as the 2 commands add different types of times. + * Cons: Users have to remember more command words which may take more time to get used to. + +* **Alternative 2:** Use the same command word + * Pros: Reduces the amount of command words that users have to remember. + * Cons: Users may get confused because the 2 commands do not add the same types of times. + +**Aspect: Display format** + +* **Alternative 1 (current choice):** Print raw list of times + * Pros: Allows users to copy and paste the intervals shown as they are in the correct format. + * Cons: May be too convoluted due to repeated information caused by reiterating the day of the time interval. + +* **Alternative 2:** Organise time intervals by day. + * Pros: Allows users to better see the intervals in each day. + * Cons: May cause inconvenience to users when they need to copy and paste time chunks should they need it again. + +-------------------------------------------------------------------------------------------------------------------- + +### Find Person and Find Group features + +#### Implementation + +The Find person/group mechanisms are facilitated by the `Model` class. + +The operation they utilise is exposed in the `Model` interface as `Model#updateFilteredPersonList(Predicate predicate)`. + +Both `FindPersonCommand` and `FindGroupCommand` implement an abstract class `FindCommand`, which helps to encapsulate the similarities between these two commands. + +Since both Find Person and Find Group commands utilise the same command word, the `FindCommandParser` will create either a `FindPersonCommand` or `FindGroupCommand` and return it as a `FindCommand` after parsing the user input. + +The following activity diagram summarizes what happens when a user executes a find command: + + + +### Find Person + +Given below is an example usage scenario and how the Find Person mechanism behaves at each step. + +Step 1. The user executes `find n/Alex John` command to find all contacts whose names contain either 'Alex' or 'John' in the address book. After parsing, a new `FindPersonCommand` object will be returned along with the corresponding `Predicate`. + +Step 2. `FindPersonCommand` is executed, in which `Model#updateFilteredPersonList()` is called with the Predicate. This through all the contacts in the address book, showing the updated list of contacts whose names start with 'Alex' or 'John' to the user. + + + +**Note:** If there are no contacts whose name contains 'Alex, or 'John', no contacts will be shown. + + + + +The following sequence diagram shows how the Find Person operation works: + + -**Note:** The lifeline for `FindGroupCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +**Note:** The lifeline for `FindPersonCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. +### Find Group + +The Find Group mechanism works like the Find Person mechanism, expect it filters contacts by a different `Predicate` which will filter for contacts who are a part of the target group. + +Additionally, it calls on an extra method `Group#getGroupRemark()`. `Group#getGroupRemarks()` will be called to display the previously saved group remarks to the user. + #### Design Considerations **Aspect: How to handle two similar but different commands (find by group and find by name)** @@ -521,7 +649,7 @@ The following sequence diagram shows how the Find Group operation works: #### Implementation -The Delete person/group mechanisms are facilitated by `AddressBook`, involving other classes like `Person` and `Group`. It implements the following operations: +The Delete person/group mechanisms are facilitated by `Model` class, which accesses the `AddressBook` class. It implements the following operations: * `AddressBook#removePerson(Person p)` — Removes Person p from the address book. * `AddressBook#removeGroup(Group g)` — Removes Group g from the address book. @@ -540,7 +668,7 @@ The following activity diagram summarizes what happens when a user executes a de Given below is an example usage scenario and how the Delete Person mechanism behaves at each step. -Step 1. The user executes `delete n/Alex Yeoh` command to delete a person named 'Alex Yeoh' in the address book. After parsing, a new `DeletePersonCommand` object will be returned. +Step 1. The user executes `delete n/Alex Yeoh` command to delete a person named 'Alex Yeoh' in the contact list. After parsing, a new `DeletePersonCommand` object will be returned. Step 2. `DeletePersonCommand` is executed, in which `Model#deletePerson("Alex Yeoh")` is called. @@ -550,7 +678,7 @@ Step 2. `DeletePersonCommand` is executed, in which `Model#deletePerson("Alex Ye -Step 3. `Model#deletePerson()` will also call `AddressBook#removePerson(Alex Yeoh)` which will remove the contact named 'Alex Yeoh' from the address book while removing it from all the groups it was part of. +Step 3. `Model#deletePerson()` will also call `AddressBook#removePerson(Alex Yeoh)` which will remove the target contact from the contact list while removing it from all the groups it was part of. The following sequence diagram shows how the Delete Person operation works: @@ -564,33 +692,9 @@ The following sequence diagram shows how the Delete Person operation works: ### Delete Group -Given below is an example usage scenario and how the Delete Group mechanism behaves at each step. - -Step 1. The user executes `delete g/CS2100` command to delete a group named 'CS2100' in the address book. After parsing, a new `DeleteGroupCommand` object will be returned. - -Step 2. `DeleteGroupCommand` is executed, in which `Model#deleteGroup("CS2100")` is called, removing the `Group` with name 'CS2100' (the target group) from the address book while returning the `Group` object. - - - -**Note:** If no such group named 'CS2100' exists, a `CommandException` will be thrown. - - - -Step 3. `Group#getListOfGroupMates()` is called to obtain a `ObservableList` of Persons that are a part of the target group. - -Step 4. The `ObservableList` is converted into a stream, where each element is a `Person`. `Person#removeGroup(CS2100)` is called for each Person in the stream, removing the target Group from the `GroupList` in `Person`. - -Step 5. `DeleteGroupCommand` creates a new `CommandResult` with the corresponding message, and returns the result to the `LogicManager`. - -The following sequence diagram shows how the Delete Group operation works: - - +The Delete Group command mechanism behaves the same as the Delete Person command above, except it deletes the target `Group` object instead of the `Person` object. - - -**Note:** The lifeline for `DeleteGroupCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. - - +Additionally, `AddressBook#removeGroup(Group g)` will remove the target group 'g' from the group lists of all the members that were a part of it. #### Design Considerations diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2f4aad546c9..d972583a058 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -78,20 +78,14 @@ Here are some annotations used in this guide:

-

Acceptable values

-

User Input +

:heavycheckmark: Acceptable values
+

User Input Description of what you are allowed to type.

-

Warning!

-

inline code - Pay attention to these points as they could lead to unexpected issues.

-
-

-
-

Warning!

-

inline code +

:exclaimation: Warning!
+

inline code Pay attention to these points as they could lead to unexpected issues.

@@ -122,16 +116,13 @@ Welcome back to ProjectPRO. Simply head over to our Features section to gain ins 3. Move the JAR file to a folder where you want to store your project details. For example, create a folder named ProjectPRO and place it on your desktop. - For Mac Users: - - ![MACGUIDE](images/UG/QUICKSTART3.png) + ![MACGUIDE](images/UG/QUICKSTART3.png) - For Windows Users: - - 4. Launch ProjectPRO. - - For Mac users: - 1. Open a command terminal - 2. type `cd Desktop` , followed by `cd ProjectPro` - 3. type `java -jar ProjectPRO.jar` to run the application. - - For Windows users: Double-click the ProjectPRO.jar file to launch the application. + 1. Open a command terminal + 2. type `cd Desktop` , followed by `cd ProjectPro` + 3. type `java -jar ProjectPRO.jar` to run the application. 5. Start using ProjectPRO! @@ -198,14 +189,14 @@ You can create a contact in your contact list.

-

Acceptable values

-

NAME +

:heavycheckmark: Acceptable values
+

NAME must be alphanumeric, cannot be blank and must not exist in the contact list.

-

PHONE +

PHONE must be a positive integer with at least 3 digits and must not exist in the contact list.

-

EMAIL +

EMAIL must be alphanumeric with a @ domain, end with a domain label at least 2 characters long and must not exist in the contact list.

-

GROUP_NAME +

GROUP_NAME must be alphanumeric. This is an optional parameter.

@@ -217,7 +208,9 @@ You can create a contact in your contact list. This creates a contact in the contact list, named John Doe, who is not in any group. ![Manage Contacts: Add](images/features/Managecontacts_add.png) - +
+

You have added John Doe to your contacts, at contact number 7

+
**Potential error(s):** - Incorrect format (e.g., no prefix, duplicate prefixes). @@ -233,14 +226,24 @@ You can delete a contact from your contact list. **Format:** `delete n/NAME` -**Acceptable values:** -- `NAME` must be alphanumeric and cannot be blank. +

+
+
:heavycheckmark: Acceptable values
+

NAME + must be alphanumeric and cannot be blank.

+

NAME + must be an existing contact in the contact list.

+
**Example(s):** -- `delete n/Nicholas Lee` - This deletes Nicholas Lee from the contact list. +- `delete n/John Doe` + This deletes John Doe from the contact list. +![Manage Contacts: Delete](images/features/Managecontacts_delete.png) +
+

You have deleted John Doe, previously contact number 7, from your contacts

+
**Potential error(s):** - Invalid format (e.g., no prefix, duplicate prefixes). @@ -255,15 +258,24 @@ You can find all the contacts from your contact list with the matching keywords. **Format:** `find n/KEYWORDS_IN_NAME` - -**Acceptable values:** -- `KEYWORDS_IN_NAME` must be alphanumeric and cannot be blank, and it is not case sensitive. +

+
+
:heavycheckmark: Acceptable values
+

KEYWORDS_IN_NAME + must be alphanumeric and cannot be blank.

+

KEYWORDS_IN_NAME + is not case-sensitive.

+
**Example(s):** -- `find n/alice alex john` - This returns all the contacts with names of Alice, Alex, and John. +- `find n/alex bernice` + This displays all the contacts with names containing Alex or Bernice. +![Manage Contacts: Find](images/features/Managecontacts_find.png) +
+

You have found all your contacts with the name Alex or Bernice

+
**Potential error(s):** - Invalid format (e.g., no prefix, duplicate prefixes). @@ -277,14 +289,21 @@ You can list all the contacts in your contact list. **Format:** `list` - -**Acceptable values:** -No additional parameters. - +

+
+
:heavycheckmark: Acceptable values
+

User Input + No additional input required.

+
**Example(s):** - `list` - This lists all the contacts in the group. + This displays all the contacts in the contact list. + +![Manage Contacts: List](images/features/Managecontacts_list.png) +
+

You can view all the contacts in your contact list

+
**Potential error(s):** @@ -295,20 +314,26 @@ No additional parameters. ### Adding a group `new` -You can create a group in your contact list. +You can create a new group in your contact list. **Format:** `new g/GROUP_NAME` - -**Acceptable values:** -- `GROUP_NAME` must be alphanumeric and cannot be blank. -- `GROUP_NAME` must not be an existing group in your contact list. +

+
+
:heavycheckmark: Acceptable values
+

GROUP_NAME + must be alphanumeric, cannot be blank, and must not exist in the contact list.

+
**Example(s):** - `new g/CS2103T tp` This creates a new group named "CS2103T tp". +![Manage Groups: New](images/features/Managegroup_new.png) +
+

You have created a new group called 'CS2103T tp'

+
**Potential error(s):** - Invalid command format (e.g., no prefix, duplicate prefixes). @@ -377,7 +402,7 @@ You can find a group in your contact list. This allows you to view the group's m **Example(s):** - `find g/CS2103T` - This returns the members and remarks of the existing "CS2103T" group in your contact list. + This displays the members and remarks of the existing "CS2103T" group in your contact list. **Potential error(s):** @@ -395,14 +420,21 @@ You can list all the groups in your contact list. **Format:** `listgroup` +

+
+
:heavycheckmark: Acceptable values
+

User Input + No additional parameters.

+
-**Acceptable values:** -No additional parameters. +**Example(s):** +- `listgroup` This lists all the groups in your contact list. +![](images/features/Managegroup_listgroup.png) -**Example(s):** -- `listgroup` - This lists all the groups in your contact list. +
+

Showing all your groups available in ProjectPRO in the output box

+
**Potential error(s):** @@ -415,24 +447,41 @@ You can add an existing contact to an existing group. **Format:** `group n/NAME g/GROUP_NAME` +

+
+
:heavycheckmark: Acceptable values
+

Name + must be alphanumeric and cannot be blank. +

+

Group_Name + must be alphanumeric and cannot be blank.

+

NAME + must not be a member of GROUP_NAME

+
-**Acceptable values:** -- `NAME` must be alphanumeric and cannot be blank. -- `NAME` must be an existing contact in your contact list. -- `GROUP_NAME` must be alphanumeric and cannot be blank. -- `GROUP_NAME` must be an existing group in your contact list. -- `NAME` must not be a member of `GROUP_NAME`. - +

+
+
:exclaimation: Warning!
+

Name + ensure the contact exists in your contact list.

+

Group_Name + ensure the group exists in your contact list.

+

NAME + ensure the contact is not already a member of GROUP_NAME

+
**Example(s):** -- `group n/Alex Yeoh g/CS2103T` - This adds your contact "Alex Yeoh" into the group "CS2103T". +- `group n/Bernice Yu g/CS2103T` + This adds your contact "Bernice Yu" into the group "CS2103T". +![](images/features/Managegroup_group.png) + +
+

You just added Bernice Yu into the group CS2103T

+
**Potential error(s):** - Incorrect format (e.g., no prefix, duplicate prefixes). - - - The contact you are trying to add is already a member of the group: `NAME is already in this group: GROUP_NAME`. @@ -442,25 +491,41 @@ You can remove a contact from a group. **Format:** `ungroup n/NAME g/GROUP_NAME` +

+
+
:heavycheckmark: Acceptable values
+

Name + must be alphanumeric and cannot be blank. +

+

Group_Name + must be alphanumeric and cannot be blank.

+
-**Acceptable values:** -- `NAME` must be alphanumeric and cannot be blank. -- `NAME` must be an existing contact in your contact list. -- `GROUP_NAME` must be alphanumeric and cannot be blank. -- `GROUP_NAME` must be an existing group in your contact list. -- `NAME` must be a member of `GROUP_NAME`. +

+
+
:exclaimation: Warning!
+

Name + ensure the contact exists in your contact list.

+

Group_Name + ensure the group exists in your contact list.

+

NAME + ensure the contact is a member of GROUP_NAME

+
**Example(s):** - `ungroup n/Alex Yeoh g/CS2103T` This removes your contact "Alex Yeoh" from the group "CS2103T". +![](images/features/Managegroup_ungroup.png) + +
+

You just removed Alex Yeoh from the group CS2103T

+
**Potential error(s):** - Incorrect format (e.g., no prefix, duplicate prefixes). - - -- The contact you are trying to remove is not a member of the group: `Bernice Yu is not in this group: CS2103T`. +- The contact you are trying to remove is not a member of the group: `Charlotte Oliveiro is not in this group: CS2103T`. ## Commands to Manage Time @@ -475,20 +540,36 @@ You can add time slots when your contacts are available. - Provide the time slot of the contact using the `t/` prefix. - Time slot is with respect to the weekly schedule. +

+
+
:heavycheckmark: Acceptable values
+

Name + must be alphanumeric and cannot be blank. +

+

FREE_TIME + must be a time slot within the current weekly schedule. Eg. Sat 1000 - Mon 1000 is not allowed as the monday here refers to next week, violating the current weekly schedule pattern.

+
-**Acceptable values:** -- `NAME` must be alphanumeric and cannot be blank. -- `FREE_TIME` must be a time slot within a weekly schedule. -- `FREE_TIME` must not be a time slot already added to the contact. - +

+
+
:exclaimation: Warning!
+

Name + ensure the contact exists in your contact list.

+

FREE_TIME + must not clash with existing time slot to the contact being added to.

+

FREE_TIME + if more than one time slot is added into the input, it cannot clash with one another.

+
**Example(s):** - `addtime n/Alex Yeoh t/mon 1400 - mon 1600` -This adds a time slot when Alex Yeoh is available to your contact list. +This adds a time slot when Alex Yeoh is available in your contact list. -Insert Image -Free time added to: Alex Yeoh +![](images/features/Managetime_addtime.png) +
+

You just added MON 1400 - MON 1600 to Alex Yeoh to indicate that he is free during that time

+
**Potential error(s):** - Contact does not exist in the contact list. @@ -504,20 +585,34 @@ You can remove available time slots of your contacts. - Provide the time slot of the contact using the `t/` prefix. - Time slot is with respect to the weekly schedule. +

+
+
:heavycheckmark: Acceptable values
+

Name + must be alphanumeric and cannot be blank. +

+

FREE_TIME + must match to the contact's existing time.

+
-**Acceptable values:** -- `NAME` must be alphanumeric and cannot be blank. -- `FREE_TIME` must be a time slot within a weekly schedule. -- `FREE_TIME` must be a time slot already added to the contact. - +

+
+
:exclaimation: Warning!
+

Name + ensure the contact exists in your contact list.

+

FREE_TIME + if more than one time slot is added into the input, it cannot clash with one another.

+
**Example(s):** - `deletetime n/Alex Yeoh t/mon 1400 - mon 1600` This removes a time slot when Alex Yeoh is available from your contact list. -Insert Image - Deleted Time From: Alex Yeoh +![](images/features/Managetime_deletetimecontact.png) +
+

You just deleted MON 1400 - MON 1600 time slot from Alex Yeoh to indicate that he is not free during that time anymore

+
**Potential error(s):** - Contact does not exist in the contact list. @@ -534,7 +629,7 @@ You list all available time slots of your contacts.

Acceptable values

-

NAME +

NAME must be alphanumeric and cannot be blank.

@@ -546,7 +641,7 @@ You list all available time slots of your contacts. ![](images/features/Managetime_listtimecontact.png)
-

We see that Alex Yeoh free on Mondays from 1400 - 1600

+

We see that Alex Yeoh is free on Mondays from 1400 - 1600

**Potential error(s):** @@ -565,17 +660,17 @@ You can add a meeting time slot for your group.

Acceptable values

-

GROUP_NAME +

GROUP_NAME must be alphanumeric and cannot be blank.

-

MEETING_TIME +

MEETING_TIME must be a time slot within a weekly schedule.

-

MEETING_TIME +

MEETING_TIME must not be a time slot already added to the group.

Warning!

-

MEETING_TIME +

MEETING_TIME can be added even if members are not available. Do coordinate with your group members on the most suitable time slots.

@@ -606,11 +701,11 @@ You can remove meeting times from your groups.

Acceptable values

-

GROUP_NAME +

GROUP_NAME must be alphanumeric and cannot be blank.

-

MEETING_TIME +

MEETING_TIME must be a time slot within a weekly schedule.

-

MEETING_TIME +

MEETING_TIME must be a time slot already added to the group.

@@ -641,7 +736,7 @@ You list meeting time for your groups.

Acceptable values

-

GROUP_NAME +

GROUP_NAME must be alphanumeric and cannot be blank.

@@ -672,15 +767,15 @@ You can find a meeting time slot for your group where everyone is available.

Acceptable values

-

GROUP_NAME +

GROUP_NAME must be alphanumeric and cannot be blank.

-

DURATION +

DURATION must be a whole number representing the meeting duration in minutes.

Warning!

-

GROUP_NAME +

GROUP_NAME must contain contacts with their free time slots.

@@ -715,8 +810,8 @@ You can view the link to our UserGuide.

Acceptable values

-

User Input - No additional input required

+

User Input + No additional input required.

@@ -744,8 +839,8 @@ Clears all entries from the contact list.

Acceptable values

-

User Input - No additional input required

+

User Input + No additional input required.

@@ -775,8 +870,8 @@ You can exit ProjectPRO.

Acceptable values

-

User Input - No additional input required

+

User Input + No additional input required.

diff --git a/docs/diagrams/AddTimeCommandSequenceDiagram.puml b/docs/diagrams/AddTimeSequenceDiagram.puml similarity index 100% rename from docs/diagrams/AddTimeCommandSequenceDiagram.puml rename to docs/diagrams/AddTimeSequenceDiagram.puml diff --git a/docs/diagrams/DeleteCommandActivityDiagram.puml b/docs/diagrams/DeleteCommandActivityDiagram.puml index 4b87a2f9da9..5db42dfb78e 100644 --- a/docs/diagrams/DeleteCommandActivityDiagram.puml +++ b/docs/diagrams/DeleteCommandActivityDiagram.puml @@ -5,7 +5,7 @@ start :User wants to delete a group or contact; :User runs the "delete" command; if () then ([Invalid command format]) -:ProjectPro throws an error; +:ProjectPRO throws an error; else (["delete g/GROUPNAME" or "delete n/NAME"]) :ProjectPRO checks if User is deleting a group or contact; if () then (["delete g/GROUPNAME"]) diff --git a/docs/diagrams/DeleteGroupSequenceDiagram.puml b/docs/diagrams/DeleteGroupSequenceDiagram.puml index 7f5fba33348..94011f9fafe 100644 --- a/docs/diagrams/DeleteGroupSequenceDiagram.puml +++ b/docs/diagrams/DeleteGroupSequenceDiagram.puml @@ -12,8 +12,6 @@ end box box Model MODEL_COLOR_T1 participant ":Model" as Model MODEL_COLOR -participant "CS2100:Group" as Group MODEL_COLOR -participant "p:Person" as Person MODEL_COLOR end box [-> LogicManager : execute("delete g/CS2100") @@ -54,21 +52,9 @@ activate DeleteGroupCommand DeleteGroupCommand -> Model : deleteGroup("CS2100") activate Model -Model --> DeleteGroupCommand : CS2100 +Model --> DeleteGroupCommand deactivate Model -DeleteGroupCommand -> Group : getListOfGroupMates() -activate Group - -Group --> DeleteGroupCommand -deactivate Group - -DeleteGroupCommand -> Person : removeGroup(CS2100) -activate Person - -Person --> DeleteGroupCommand -deactivate Person - create CommandResult DeleteGroupCommand -> CommandResult activate CommandResult diff --git a/docs/diagrams/FindPersonSequenceDiagram.puml b/docs/diagrams/FindPersonSequenceDiagram.puml new file mode 100644 index 00000000000..04956ff29d4 --- /dev/null +++ b/docs/diagrams/FindPersonSequenceDiagram.puml @@ -0,0 +1,70 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":FindCommandParser" as FindCommandParser LOGIC_COLOR +participant "d:FindPersonCommand" as FindPersonCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +end box + +[-> LogicManager : execute("find n/Alex John") +activate LogicManager + +LogicManager -> AddressBookParser : parseCommand("find n/Alex John") +activate AddressBookParser + +create FindCommandParser +AddressBookParser -> FindCommandParser +activate FindCommandParser + +FindCommandParser --> AddressBookParser +deactivate FindCommandParser + +AddressBookParser -> FindCommandParser : parse("n/Alex John") +activate FindCommandParser + +create FindPersonCommand +FindCommandParser -> FindPersonCommand +activate FindPersonCommand + +FindPersonCommand --> FindCommandParser : d +deactivate FindPersonCommand + +FindCommandParser --> AddressBookParser : d +deactivate FindCommandParser +'Hidden arrow to position the destroy marker below the end of the activation bar. +FindCommandParser -[hidden]-> AddressBookParser +destroy FindCommandParser + +AddressBookParser --> LogicManager : d +deactivate AddressBookParser + +LogicManager -> FindPersonCommand : execute() +activate FindPersonCommand + +FindPersonCommand -> Model : updateFilteredPersonList(NameContainsKeywordsPredicate) +activate Model + +Model --> FindPersonCommand +deactivate Model + +create CommandResult +FindPersonCommand -> CommandResult +activate CommandResult + +CommandResult --> FindPersonCommand +deactivate CommandResult + +FindPersonCommand --> LogicManager : result +deactivate FindPersonCommand + +[<--LogicManager +deactivate LogicManager +@enduml diff --git a/docs/diagrams/ListGroupSequenceDiagram.puml b/docs/diagrams/ListGroupSequenceDiagram.puml new file mode 100644 index 00000000000..f8289680c91 --- /dev/null +++ b/docs/diagrams/ListGroupSequenceDiagram.puml @@ -0,0 +1,72 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":ListGroupCommandParser" as ListGroupCommandParser LOGIC_COLOR +participant "c:ListGroupCommand" as ListGroupCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +end box + + +[-> LogicManager : execute("listgroup") +activate LogicManager + +LogicManager -> AddressBookParser : parseCommand("listgroup") +activate AddressBookParser + +create ListGroupCommandParser +AddressBookParser -> ListGroupCommandParser +activate ListGroupCommandParser + +ListGroupCommandParser --> AddressBookParser +deactivate ListGroupCommandParser + +AddressBookParser -> ListGroupCommandParser : parse("listgroup") +activate ListGroupCommandParser + +create ListGroupCommand +ListGroupCommandParser -> ListGroupCommand +activate ListGroupCommand + +ListGroupCommand --> ListGroupCommandParser : c +deactivate ListGroupCommand + +ListGroupCommandParser --> AddressBookParser : c +deactivate ListGroupCommandParser +'Hidden arrow to position the destroy marker below the end of the activation bar. +ListGroupCommandParser -[hidden]-> AddressBookParser +destroy ListGroupCommandParser + +AddressBookParser --> LogicManager : c +deactivate AddressBookParser + +LogicManager -> ListGroupCommand : execute() +activate ListGroupCommand + +ListGroupCommand -> Model : getFilteredGroupList() +activate Model + +Model --> ListGroupCommand +deactivate Model + +create CommandResult +ListGroupCommand -> CommandResult +activate CommandResult + +CommandResult --> ListGroupCommand +deactivate CommandResult + +ListGroupCommand --> LogicManager : result +deactivate ListGroupCommand + +[<--LogicManager +deactivate LogicManager + +@enduml diff --git a/docs/diagrams/ListTimeActivityDiagram.puml b/docs/diagrams/ListTimeActivityDiagram.puml new file mode 100644 index 00000000000..0db8257dedd --- /dev/null +++ b/docs/diagrams/ListTimeActivityDiagram.puml @@ -0,0 +1,29 @@ +@startuml +'https://plantuml.com/activity-diagram-beta + +start +:User wants to list the times of a group or contact; +:User runs the "listtime" command; +if () then ([Invalid command format]) +:ProjectPRO throws an error; +else (["listtime g/GROUPNAME" or "listtime n/NAME"]) +:ProjectPRO checks if User is listing time of a group or contact; +if () then (["listtime g/GROUPNAME"]) +:ProjectPRO checks if group exists; + if () then ([Group exists]) + : ProjectPRO lists times of specified group; + else([Else]) + : ProjectPRO throws an error; + endif +else(["listtime n/NAME"]) +: ProjectPRO checks if contact exists; + if () then ([Contact exists]) + : ProjectPRO lists times of specified contact; + else([Else]) + : ProjectPRO throws an error; + endif +endif +endif +stop + +@enduml diff --git a/docs/team/coderhuang559.md b/docs/team/coderhuang559.md index 92b16ed6d80..d78bd89a385 100644 --- a/docs/team/coderhuang559.md +++ b/docs/team/coderhuang559.md @@ -36,9 +36,9 @@ Given below are my contributions to the project. * **Documentation**: * User Guide: - * Added documentation for the features `remark` for contacts, `listtime` for contacts, `addmeeting` for groups and `deletetime` for groups. [\#145](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/145) + * Added documentation for the features `remark` for contacts, `listtime` for contacts, `addmeeting` for groups and `deletetime` for groups. [\#144](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/145) * Developer Guide: - * Added implementation details of the `remark` [\#112](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/112/files) and `addgroup` [\#226](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/226/files) feature. + * Added implementation details of the `remark` [\#112](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/112/files), `listtime` [\#226](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/226/files), and `addmeeting` features. * Added activity and sequence diagrams for the above functions. This includes for delete person time command, shown here. * diff --git a/docs/team/lerxuann.md b/docs/team/lerxuann.md index 0a56fbeed17..34a3d6c218a 100644 --- a/docs/team/lerxuann.md +++ b/docs/team/lerxuann.md @@ -43,23 +43,7 @@ Given below are my contributions to the project. * Added documentation for the features `add contact` and `delete contact`. [\#147](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/147) * Resolved inconsistencies in existing documentation in multiple features, including `delete contact`, `find contact` and `list`: [\#228](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/228) * Developer Guide: - * Added implementation details of the `delete contact` and `delete group` features. [\#116](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/116) - -[//]: # (* **Community**:) - -[//]: # ( * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]()) - -[//]: # ( * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]())) - -[//]: # ( * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]())) - -[//]: # ( * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]())) - -[//]: # (* **Tools**:) - -[//]: # ( * Integrated a third party library (Natty) to the project ([\#42]())) - -[//]: # ( * Integrated a new Github plugin (CircleCI) to the team repo) + * Added implementation details of the `delete`, `find`, `list` [\#265](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/265) and `listgroup` [\#268](https://github.com/AY2324S1-CS2103T-T10-3/tp/pull/268) features. * **Contributions beyond project team** * Meticulously reviewed other groups' works and provided feedback on potential bugs [here](https://github.com/lerxuann/ped). diff --git a/src/main/java/seedu/address/logic/commands/DeleteGroupCommand.java b/src/main/java/seedu/address/logic/commands/DeleteGroupCommand.java index 5872fe79d64..04f8fb4f7ff 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteGroupCommand.java @@ -2,12 +2,10 @@ import static java.util.Objects.requireNonNull; -import javafx.collections.ObservableList; import seedu.address.commons.util.ToStringBuilder; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.group.Group; -import seedu.address.model.person.Person; /** * Removes group from the addressbook and person. @@ -25,16 +23,6 @@ public CommandResult execute(Model model) throws CommandException { requireNonNull(model); Group groupToDelete = model.deleteGroup(this.groupName); - //Delete group from all People - ObservableList groupMates = groupToDelete.getListOfGroupMates(); - groupMates.stream().forEach(p -> { - try { - p.removeGroup(groupToDelete); - } catch (CommandException e) { - throw new RuntimeException(); - } - }); - return new CommandResult(String.format(MESSAGE_DELETE_GROUP_SUCCESS, groupToDelete.getGroupName())); } diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index 8043475542b..b66586b66e8 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -125,17 +125,6 @@ public void removePerson(Person key) { }); } - /** - * Adds a person to a group - * @param person person to add - * @param group group to add person to - */ - public void addPersonToGroup(Person person, Group group) { - requireNonNull(person); - requireNonNull(group); - GroupList groups = person.getGroups(); - } - public Person getPerson(String personName) throws CommandException { // person list get that person object with same name return persons.getPerson(personName); @@ -168,6 +157,14 @@ public void addGroup(Group g) { */ public void removeGroup(Group g) { groups.remove(g); + + g.toStream().forEach(p -> { + try { + p.removeGroup(g); + } catch (CommandException e) { + throw new RuntimeException(); + } + }); } /** diff --git a/src/test/java/seedu/address/logic/commands/DeleteGroupCommandTest.java b/src/test/java/seedu/address/logic/commands/DeleteGroupCommandTest.java index f4679e1d2ff..9783a25b7f3 100644 --- a/src/test/java/seedu/address/logic/commands/DeleteGroupCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/DeleteGroupCommandTest.java @@ -307,6 +307,13 @@ public Group deleteGroup(String groupName) throws CommandException { for (Group group : groups) { if (group.getGroupName().equals(groupName)) { groups.remove(group); + persons.forEach(p -> { + try { + p.removeGroup(group); + } catch (CommandException e) { + throw new RuntimeException(e); + } + }); return group; } } diff --git a/src/test/java/seedu/address/logic/commands/GroupPersonCommandTest.java b/src/test/java/seedu/address/logic/commands/GroupPersonCommandTest.java index 119189c07c6..8f2d0711583 100644 --- a/src/test/java/seedu/address/logic/commands/GroupPersonCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/GroupPersonCommandTest.java @@ -244,7 +244,7 @@ private class ModelStubWithGroup extends ModelStub { ModelStubWithGroup() { this.personsAdded = TypicalPersons.getTypicalPersons(); - this.groupsAdded = TypicalGroups.getTypicalPGroup(); + this.groupsAdded = TypicalGroups.getTypicalGroupList(); } @Override diff --git a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java index 4e5ce9200c8..5fadd96108a 100644 --- a/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java +++ b/src/test/java/seedu/address/storage/JsonAddressBookStorageTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static seedu.address.testutil.Assert.assertThrows; -import static seedu.address.testutil.TypicalPersons.ALICE; import static seedu.address.testutil.TypicalPersons.HOON; import static seedu.address.testutil.TypicalPersons.IDA; import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook; @@ -73,7 +72,6 @@ public void readAndSaveAddressBook_allInOrder_success() throws Exception { // Modify data, overwrite exiting file, and read back original.addPerson(HOON); - original.removePerson(ALICE); jsonAddressBookStorage.saveAddressBook(original, filePath); readBack = jsonAddressBookStorage.readAddressBook(filePath).get(); assertEquals(original, new AddressBook(readBack)); diff --git a/src/test/java/seedu/address/testutil/TypicalGroups.java b/src/test/java/seedu/address/testutil/TypicalGroups.java index 166599ba4be..c788128900b 100644 --- a/src/test/java/seedu/address/testutil/TypicalGroups.java +++ b/src/test/java/seedu/address/testutil/TypicalGroups.java @@ -33,7 +33,7 @@ public class TypicalGroups { .withTimeIntervalList("mon 1200 - mon 1400", "wed 1600 - thu 1800") .build(); - public static GroupList getTypicalPGroup() { + public static GroupList getTypicalGroupList() { GroupList groupList = new GroupList(); Group[] groupArray = {CS2100, CS2102, CS2103, CS2105}; Arrays.stream(groupArray).forEach(groupList::add);