Skip to content

Commit

Permalink
Merge pull request #181 from zekone/add-tag-DG
Browse files Browse the repository at this point in the history
Add tag feature to DG
  • Loading branch information
AndrewJanong authored Nov 12, 2023
2 parents 83d6d74 + 4bccc58 commit b3213b6
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 11 deletions.
72 changes: 72 additions & 0 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,78 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa

This section describes some noteworthy details on how certain features are implemented.

### Tag feature
This feature allows users to add and remove `Tag` to any `Person` in the contact list. It provides an easy way for users to catrgorize their contacts.

#### Overview:
The adding and removing of `Tag` begins with the parsing of the `AddTagCommand` and `DeleteTagCommand` using the `AddTagCommandParser` and `DeleteTagCommandparser` respectively. The `AddTagCommand` and `DeleteTagCommand` will then be executed by the `Model`.

The activity diagram below shows the action sequence of adding one or more `Tag` to a contact.

<puml src="diagrams/tag/TagSequenceDiagram.puml"/>

<box type="info" seamless>

**Note:** The sequence diagram for removing `Tag` is similar to adding `Tag`. Simply replace `AddCommandParser` with `DeleteCommandParser`, `AddTagCommandParser` with `DeleteTagCommandParser`, and `AddTagCommand` with `DeleteTagCommand`.

</box>

##### Implementing `AddTagCommandParser` and `DeleteTagCommandParser`
Both implements the `Parser` interface, parsing two main arguments:
1. `contactId`: the one-based index of the contact shown in the GUI.
1. `taglist`: the unique set of `Tag` to add/delete.
* The set of tags is parsed using the `parseTags` method in the `ParseUtil` utility class, which puts the collection of tag names given by the user into a `HashSet`.

`contactId` and `taglist` is then use to create the `AddTagCommand`/`DeleteTagCommand` object.

For the details of how parsing works, see the section on [Logic Component](#logic-component).

##### Implementing `AddTagCommand`
`AddTagCommand` extends from the abstract class `AddCommand`, inheriting `add` as the primary command word and having `tag` as its secondary command word. It internally stores `contactId` (the index of the contact) and `toAdd` (the set `Tag` to add) which is given by the [parser](#implementing-addtagcommandparser-and-deletetagcommandparser).

When the command is execute, it carries out the following operations:
1. Using the `contactId`, it will first check if the `person` exist in the address book by calling `Model`'s `findPersonByUserFriendlyId` method.
* A `CommandException` is thrown if the person does not exist.
1. The set of tags is then added to the person's tag list by calling the `addTags` method in `Person`.
1. The `Model`'s `setPerson` method is used to update the person.
1. Lastly a `CommandResult` with the success message is returned.

The following activity diagram summarizes what happens when `AddTagCommand` is executed:

<puml src="diagrams/tag/AddTagActivityDiagram.puml"/>

##### Implementing `DeleteTagCommand`
`DeleteTagCommand` extends from the abstract class `DeleteCommand`, inheriting `delete` as the primary command word and having `tag` as its secondary command word. It internally stores `contactId` (the index of the contact) and `toDelete` (the set `Tag` to delete) which is given by the [parser](#implementing-addtagcommandparser-and-deletetagcommandparser).

When the command is execute, it carries out the following operations:
1. Using the `contactId`, it will first check if the `person` exist in the address book by calling `Model`'s `findPersonByUserFriendlyId` method.
* A `CommandException` is thrown if the person does not exist.
1. Loop through every `Tag` that the person has, separating those that be found in `toDelete` and those not found.
1. The set of tags found in `toDelete` is then deleted from the person's tag list by calling the `removeTags` method in `Person`.
1. The `Model`'s `setPerson` method is used to update the person.
1. Lastly a `CommandResult` with the success message is returned.

The following activity diagram summarizes what happens when the `DeleteTagCommand` is executed:

<puml src="diagrams/tag/DeleteTagActivityDiagram.puml"/>

#### Design Considerations:

**Aspect: Deletion of non-existing tag:**

* **Alternative 1:** Ignore and proceed as normal.
* Pros: Easy to implement. Furthermore, since outcome of proceeding and not proceeding is the same, there will not be a severe consequence of proceeding.
* Cons: Does not reflect true behavior, and users may be confused by success message.

* **Alternative 2:** Does not proceed.
* Pros: Users will be made aware of their mistake and prevents executing potentially wrong commands.
* Cons: If the command was intentional, time is wasted for user to correct their command.

* **Alternative 3 (current choice):** Proceed but inform user that some tags are non-existing.
* Pros: Users will be made aware of their mistake. Does not waste time on correcting the command if the command was intentional.
* Cons: Harder to implement.


### Enhanced help feature

#### Design considerations:
Expand Down
22 changes: 11 additions & 11 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ Unsuccessful output:
* Contact already exists: `This contact already exists in the contact list`
* Invalid format<br>
```
Invalid command format!
add contact: Adds a contact to the contact list.
Invalid command format!
add contact: Adds a contact to the contact list.
Usage: add contact -n NAME -p PHONE -e EMAIL -a ADDRESS [-t TAGNAME...]
Example: add contact -n John Doe -p 98765432 -e [email protected] -a 311, Clementi Ave 2, #02-25 -t frontend
Example: add contact -n John Doe -p 98765432 -e [email protected] -a 311, Clementi Ave 2, #02-25 -t frontend
```
* Invalid email:<br>
```
Expand Down Expand Up @@ -194,7 +194,7 @@ Unsuccessful output:
* Invalid index (out of range): `The person index provided is invalid`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
delete contact: Deletes a contact by its index number used in the displayed contact list.
Parameters: INDEX (must be a positive integer)
Example: delete contact 1
Expand Down Expand Up @@ -232,7 +232,7 @@ Unsuccessful output:
* Invalid index (out of range): `Can not find the target contact with ID: 100`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
add tag: Adds tags to a contact from the contact list.
Usage: add tag -id CONTACT_ID -t TAGNAME...
```
Expand All @@ -256,7 +256,7 @@ Unsuccessful output:
* Invalid index (out of range): `Can not find the target contact with ID: 100`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
delete tag: Delete one or more tags from a contact.
Usage: delete tag -id CONTACT_ID -t TAGNAME...
```
Expand All @@ -278,7 +278,7 @@ Unsuccessful output:
* Invalid index (out of range): `Can not find the target contact with ID: 100`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
add note: Adds a note to a contact from the contact list.
Usage: add note -id CONTACT_ID -tit NOTE_TITLE -con NOTE_CONTENT
```
Expand All @@ -302,7 +302,7 @@ Unsuccessful output:
* Invalid note index: `Note not found: ID = 5`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
delete note: Deletes a note from a contact.
Usage: delete note -id CONTACT_ID -nid NOTE_ID
```
Expand Down Expand Up @@ -333,7 +333,7 @@ Successful output:
Unsuccessful ouput:
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
list events: Shows a list of all events or events within a specified time interval.
Usage: list events [-descending] [-st filter_start_time] [-et filter_end_time] (-st and -et must either both present or both not present)
```
Expand All @@ -360,7 +360,7 @@ Unsuccessful output:
* Invalid time format: `Invalid date-time format! Text '29/05/2024' could not be parsed at index 2`
* Invalid command format:<br>
```
Invalid command format!
Invalid command format!
add event: Adds an event to a contact.
Usage: add event -id CONTACT_ID -en EVENT_NAME -st START_TIME [-et END_TIME] [-loc LOCATION] [-info INFORMATION]
```
Expand All @@ -385,7 +385,7 @@ Unsuccessful output:
* Invalid note index: `Event not found: ID = 5`
* Invalid format:<br>
```
Invalid command format!
Invalid command format!
delete event: Deletes an event from a contact.
Usage: delete event -id CONTACT_ID -eid EVENT_ID
```
Expand Down
20 changes: 20 additions & 0 deletions docs/diagrams/tag/AddTagActivityDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@startuml
skin rose
skinparam ActivityFontSize 15
skinparam ArrowFontSize 12
start
:User executes add tag command;

'Since the beta syntax does not support placing the condition outside the
'diamond we place it as the true branch instead.

if () then ([person exists])
:Add new tags to person;
:Model updates the person in the address book;
:Returns result message notifying
that the tags have been added;
else ([else])
:Throw CommandException;
endif
stop
@enduml
22 changes: 22 additions & 0 deletions docs/diagrams/tag/DeleteTagActivityDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@startuml
skin rose
skinparam ActivityFontSize 15
skinparam ArrowFontSize 12
start
:User executes delete tag command;

'Since the beta syntax does not support placing the condition outside the
'diamond we place it as the true branch instead.

if () then ([person exists])
:Separate tags that exists in the tag list
from those that do not;
:Delete only those that exists in the tag list;
:Model updates the person in the address book;
:Returns result message with a list of tags that have
been deleted and a list of tags that cannot be found;
else ([else])
:Throw CommandException;
endif
stop
@enduml
69 changes: 69 additions & 0 deletions docs/diagrams/tag/TagSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@startuml
!include ../style.puml
skinparam ArrowFontStyle plain

participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant ":AddCommandParser" as AddCommandParser LOGIC_COLOR
participant ":AddTagCommandParser" as AddTagCommandParser LOGIC_COLOR
participant ":AddTagCommand" as AddTagCommand LOGIC_COLOR
participant "commandResult:CommandResult" as CommandResult LOGIC_COLOR

[-> LogicManager : execute(commandText)
activate LogicManager

LogicManager -> AddressBookParser : parseCommand(commandText)
activate AddressBookParser

create AddCommandParser
AddressBookParser -> AddCommandParser
activate AddCommandParser

AddCommandParser --> AddressBookParser
deactivate AddCommandParser

AddressBookParser -> AddCommandParser : parse(commandText)
activate AddCommandParser

create AddTagCommandParser
AddCommandParser -> AddTagCommandParser : parse(commandText)
activate AddTagCommandParser

create AddTagCommand
AddTagCommandParser -> AddTagCommand
activate AddTagCommand

AddTagCommand --> AddTagCommandParser
deactivate AddTagCommand

AddTagCommandParser --> AddCommandParser
deactivate AddTagCommandParser
AddTagCommandParser -[hidden]-> AddCommandParser
destroy AddTagCommandParser

AddCommandParser --> AddressBookParser
deactivate AddCommandParser
AddCommandParser -[hidden]-> AddressBookParser
destroy AddCommandParser

AddressBookParser --> LogicManager
deactivate AddressBookParser

LogicManager -> AddTagCommand : execute()
activate AddTagCommand

create CommandResult
AddTagCommand -> CommandResult
activate CommandResult

CommandResult --> AddTagCommand : commandResult
deactivate CommandResult

AddTagCommand --> LogicManager : commandResult
deactivate AddTagCommand
AddTagCommand -[hidden]-> LogicManager
destroy AddTagCommand

[<--LogicManager : commandResult
deactivate LogicManager
@enduml

0 comments on commit b3213b6

Please sign in to comment.