@@ -280,17 +331,11 @@ Notice that the states are copied into the `persons` list instead of replacing i
The following sequence diagram shows how an undo operation goes through the `Logic` component:
-
-
-
-
-**Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
-
-
+
Similarly, how an undo operation goes through the `Model` component is shown below:
-
+
The `redo` command does the opposite — it calls `Model#redo()`, which will:
1. Copy the `persons` list into the `undoStack`.
@@ -305,14 +350,14 @@ The `redo` command does the opposite — it calls `Model#redo()`, which will:
Step 5. The user then decides to execute the command `list`. Commands that do not modify the `persons` list, such as `list`, will usually not call `AddressBook#save()`, `Model#undo()` or `Model#redo()`. Thus, the `undoStack` and `redoStack` remains unchanged.
-
+
-Step 6. The user executes `clear`, which calls `AddressBook#save()`.
-Since there are still states in the `redoStack`, all states in the `redoStack` will be removed.
+Step 6. The user executes `clear`, which eventually calls `save()`.
+Since there are still states in the `redoStack`, all states in the `redoStack` (State 2) will be removed.
-Reason: It no longer makes sense to redo the `add n/David ...` command and ignore the `clear` command. This is the behavior that most modern desktop applications follow.
+Reason: It no longer makes sense to redo the `add n/David ...` command (State 2), and ignore the `clear` command (State 3). This is the behavior that most modern desktop applications follow.
-
+
The following activity diagram summarizes what happens when a user executes a new command (excluding undo & redo):
@@ -335,7 +380,7 @@ The following activity diagram summarizes what happens when a user executes a ne
* Pros:
* Saves history between different program launches.
* Cons:
- * May have performance issues with many storage accesses.
+ * May have performance issues with frequent storage access.
* Increases coupling as `Model` will now need a reference to `Storage`.
@@ -344,7 +389,7 @@ The following activity diagram summarizes what happens when a user executes a ne
* Reduces memory footprint as only 1 String is used as compared to a many objects per Person.
* Faster than JSON files as there are no accesses to storage.
* Cons:
- * May have performance issues as it has to be deserialized each time.
+ * May have performance issues as it needs to be deserialized each time.
* **Alternative 4:** Each command implements their own specific `undo()` and `redo()` methods
@@ -352,8 +397,8 @@ The following activity diagram summarizes what happens when a user executes a ne
* Will use less memory (e.g. for `delete`, just save the person being deleted).
* Best performance.
* Cons:
- * We must ensure that the implementation of each individual `undo` command is correct.
- This would be especially difficult for commands that modify multiple people at once (e.g. `asset` editing commands)
+ * We must ensure that the implementation of each command's respective `undo` command is correct.
+ This would be especially difficult for commands that modify multiple people at once (e.g. `asset` command)
**Aspect: Data structure used to store undo & redo states:**
@@ -382,14 +427,33 @@ The following activity diagram summarizes what happens when a user executes a ne
* Simple data structure.
* Cons:
* Time-consuming to implement: Unfortunately, the built-in LinkedList does not have a method to drop all nodes after a certain index.
- Hence a custom data structure would have to be used in order to quickly drop nodes after a certain index.
- There would be no benefits of using a LinkedList here otherwise.
+ Hence a custom data structure would have to be implemented in order to have this feature.
+ There will not be much benefits of using a LinkedList here otherwise.
-### \[Proposed\] Data archiving
+### Command History feature
+
+The `CommandHistory` class is an abstraction for a command history data structure.
+It stores all command strings that were successfully executed by the user.
+
+When the user executes a command successfully, `LogicManager` calls the `add()` method in `CommandHistory` to store the command string.
+
+
+
+
+
+`CommandExecutor` is an interface that has the methods `execute()`, `getPreviousCommandText()` and `getNextCommandText()`.
+A private nested class `RecordedCommandExecutor` in `MainWindow` implements this interface.
+
+When the user presses the `UP` key, a `KeyEvent` is generated by JavaFX, which is then handled by the `CommandBox` class through the `handleKeyPressed()` method.
+
+The following sequence diagram shows the interaction between the classes when the user presses the `UP` key.
+Note that `TextField` is a class in JavaFX. `CommandBox` has a `textField` attribute.
-_{Explain here how the data archiving feature will be implemented}_
+
+
+A similar interaction occurs when the user presses the `DOWN` key.
--------------------------------------------------------------------------------------------------------------------
@@ -410,7 +474,7 @@ _{Explain here how the data archiving feature will be implemented}_
**Target user profile**:
* logistics managers
-* has a need to keep track of a significant number of contacts and assets they are responsible for
+* has a need to keep track of a significant number of contacts and assets
* prefers desktop apps over other types
* prefers typing to other forms of input
* can type fast
@@ -427,17 +491,18 @@ may be cumbersome to use as they
* are not optimised for typing only
Therefore, the application aims to deliver the following:
-* manage contacts and associated assets faster than a typical mouse/GUI driven app
+* manage contacts and associated assets faster than a typical mouse/GUI focused app
* easily annotate contacts and assets with details
* easily search for information by any category
* easily copy contact information to clipboard
-* is lightweight and able to import/export data in easy-to-view format
+* import/export data in an easy-to-view format
+* is lightweight
---
### User stories
-Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`
+Priorities: High (must have): `* * *`, Medium (nice to have): `* *`, Low (unlikely to have): `*`
| Priority | As a ... | I want to ... | So that I can ... |
|-----------|---------------|------------------------------------------------------------------|-------------------------------------------------------------------------------------|
@@ -449,16 +514,16 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
| `* * *` | user | search contacts by any category (e.g. name, asset, etc.) | easily find the relevant contact |
| `* * *` | user | see usage instructions | refer to instructions and examples when I forget how to use certain commands |
| `* * ` | user | add tags to contacts | categorize them according to my preferences and workflow |
-| `* *` | user | quickly paste contact information (e.g. email) onto the clipboard | use the contact information immediately after finding it |
+| `* *` | user | quickly copy contact information (e.g. email) onto the clipboard | use the contact information immediately after finding it |
| `* *` | user | see no advertisements | not be distracted from my tasks |
| `* *` | user | add secondary personnel associated with an asset | have a backup contact if the main person is unreachable |
| `* *` | user | toggle between light/dark theme | customize the app to my preferences |
| `* *` | user | resize the app’s window | easily use multiple apps at once |
-| `* *` | user | change the profile picture of each contact | easily identify them |
+| `* *` | user | add a profile picture to each contact | easily identify them |
| `* *` | user | easily search within the system even if I mistype a few words | more easily locate relevant information |
| `* *` | new user | view a drop-down suggestion of commands | efficiently navigate and utilize the app without extensive prior knowledge |
| `* *` | hurried user | have commands even with extra whitespaces accepted | not waste time retyping commands |
-| `* *` | advanced user | type shorter commands | type commands faster |
+| `* *` | advanced user | type shorter commands | manage my contacts and assets quicker |
| `* *` | advanced user | use keyboard shortcuts | use the app more efficiently |
| `*` | advanced user | add custom fields | add more information to contacts |
@@ -473,7 +538,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
1. User requests to add a contact.
2. User specifies details of the contact.
3. AB adds the contact.
-4. AB shows a success message and new contact details to the user.
+4. AB shows a success message and details of the added contact.
Use case ends.
**Extensions**
@@ -500,7 +565,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
1. User requests to search contacts.
2. User specifies details to search by.
3. AB displays all matching contacts.
-4. AB shows a success message and number of matching users to the user.
+4. AB shows a success message and the number of matching users.
Use case ends.
**Extensions**
@@ -513,19 +578,21 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
--- {.dotted}
-**Use case: UC4 - Edit contacts**
+**Use case: UC4 - Edit contact**
**MSS**
-1. User !!lists contacts(UC2)!!.
+1. User !!searches for contact (UC3)!!.
2. User requests to edit a contact.
3. User specifies the index of the contact and details to edit.
4. AB updates the contact.
-5. AB shows a success message and the new contact details to the user.
+5. AB shows a success message and details of the updated contact.
Use case ends.
**Extensions**
-1a. AB displays no contacts.
-Use case ends.
+1a. User could not find contact.
+1a1. User !!searches again (UC3)!!.
+Step 1a1 is repeated until contact is found.
+Use case resumes from step 2.
3a. AB detects user input is invalid.
3a1. AB displays an error message.
3a2. User enters new input.
@@ -539,7 +606,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
1. User requests to edit an asset.
2. User specifies the old and new name for the asset.
3. AB updates all relevant assets.
-4. AB shows a success message and the new asset details to the user.
+4. AB shows a success message and details of the new asset.
Use case ends.
**Extensions**
@@ -554,17 +621,19 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
**Use case: UC6 - Delete contact**
**MSS**
-1. User !!lists contacts(UC2)!!.
+1. User !!searches for contact (UC3)!!.
2. User requests to delete a contact.
3. User specifies the index of the contact to delete.
4. AB deletes the contact.
-5. AB shows a success message and the deleted contact details to the user.
+5. AB shows a success message and details of the deleted contact.
Use case ends.
**Extensions**
-1a. AB displays no contacts.
-Use case ends.
+1a. User could not find contact.
+1a1. User !!searches again (UC3)!!.
+Step 1a1 is repeated until contact is found.
+Use case resumes from step 2.
3a. AB detects user input is invalid.
3a1. AB displays an error message.
3a2. User enters new input.
@@ -576,39 +645,29 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
**Use case: UC7 - Undo command**
**MSS**
1. User requests to undo a command.
-2. AB undoes the previous command.
-3. AB shows a success message to the user.
+2. AB undoes the last modifying command.
+3. AB shows a success message.
Use case ends.
**Extensions**
-1a. AB detects user input is invalid.
-1a1. AB displays an error message.
-1a2. User enters new input.
-Steps 1a1-1a2 are repeated until user input is valid.
-Use case resumes from step 2.
-1b. AB detects there is no previous command to undo.
-1b1. AB lets the user know there is no command to undo.
+1a. AB detects there is no previous command to undo.
+1a1. AB lets the user know there is no command to undo.
Use case ends.
--- {.dotted}
-**Use case: UC8 - Redo undo command**
+**Use case: UC8 - Redo command**
**MSS**
-1. User requests to redo an undo command.
-2. AB redoes the command previously undone-ed.
-3. AB shows a success message to the user.
+1. User requests to redo an undone command.
+2. AB redoes the command that was previously undone.
+3. AB shows a success message.
Use case ends.
**Extensions**
-1a. AB detects user input is invalid.
-1a1. AB displays an error message.
-1a2. User enters new input.
-Steps 1a1-1a2 are repeated until user input is valid.
-Use case resumes from step 2.
-1b. AB detects there is no previous undo command to redo.
-1b1. AB lets the user know there is no undo command to redo.
+1a. AB detects there is no previously undone command to redo.
+1a1. AB lets the user know there is no undo command to redo.
Use case ends.
--- {.dotted}
@@ -617,29 +676,21 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
**MSS**
1. User requests to clear all contact data.
2. AB clears all contact data.
-3. AB shows a success message to the user.
+3. AB shows a success message.
Use case ends.
-**Extensions**
-
-1a. AB detects user input is invalid.
-1a1. AB displays an error message.
-1a2. User enters new input.
-Steps 1a1-1a2 are repeated until user input is valid.
-Use case resumes from step 2.
-
--- {.dotted}
-**Use case: UC10 - Add person to json file directly**
+**Use case: UC10 - Add person to JSON file directly**
**MSS**
-1. User adds a new person to the json file.
+1. User adds a new person to the JSON file.
2. User runs the application.
-3. AB reads the json file and shows the updated contact list.
+3. AB reads the JSON file and shows the updated contact list.
Use case ends.
**Extensions**
-2a. AB detects that the json file is invalid.
+2a. AB detects that the JSON file is invalid.
2a1. AB displays a warning and loads an empty address book.
Use case ends.
@@ -697,15 +748,14 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
* **AddressBook**: The underlying system that AssetBook is built on
* **Asset**: An item of logistical significance, may be amenities or inventory
-* **Clipboard**: The computer's storage for data that is copied and that will be produced by the paste command
+* **Clipboard**: The computer's storage for data that is copied and that can be retrieve with the paste command
* **Command**: Text that a user inputs to interact with the application
-* **Command Line Interface(CLI)**: An interface where text commands are inputted by users to interact with the computer
-* **Graphical User Interface(GUI)**: The visual display of an application through which a user interacts with the computer
+* **Command Line Interface (CLI)**: An interface where text commands are inputted by users to interact with the computer
+* **Graphical User Interface (GUI)**: The visual display of an application through which a user interacts with the computer
* **Logistics Manager**: Anyone who manages inventory or amenities in a professional capacity
-* **Mainstream OS**: Windows, Linux, Unix, MacOS
-* **Person-In-Charge(PIC)**: A contact responsible for an asset
-* **Point-of-Contact(PoC)**: A contact representing a responsible entity like a department or external business
-* **Tag**: User added information associated to a contact e.g. `retired`, `temp staff`, ...
+* **Mainstream OS**: Windows, Linux, MacOS
+* **Person-In-Charge (PIC)**: A contact responsible for an asset
+* **Point-of-Contact (PoC)**: A contact representing a responsible entity like a department or external business
--------------------------------------------------------------------------------------------------------------------
@@ -756,31 +806,36 @@ testers are expected to do more *exploratory* testing.
1. Prerequisites: List all persons using the `list` command. Multiple persons in the list.
1. Test case: `delete 1`
- Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated.
+ Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message.
1. Test case: `delete 0`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same.
+ Expected: No person is deleted. Error details shown in the status message.
- 1. Other incorrect `delete` commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
+ 1. Other incorrect `delete` commands to try: `delete`, `delete 0`, `delete x`, `...` (where x is larger than the list size)
Expected: Similar to previous.
### Saving data
-1. Dealing with missing/corrupted data files
+1. Dealing with corrupted data file
- 1. Modify or delete data files.
+ 1. Modify data file into an invalid format. Eg. Removing fields of a contact, changing non-list fields into lists, etc.
- 1. Open AssetBook. If AssetBook is open, close and reopen it.
- Expected: AssetBook will detect missing/corrupted data files, show a warning to the user about the missing/corrupted data files, and start with an empty list.
+ 1. Open AssetBook. If AssetBook was already opened, close and reopen it.
+ Expected: AssetBook will detect that the data file is corrupted, warn the user that the data file could not be loaded and that entering a command would reset it, and start with an empty list.
--------------------------------------------------------------------------------------------------------------------
## **Appendix: Planned Enhancements**
-1. **Feature Flaw** - Currently, `redo` and `undo` commands only display a success message without any additional information. In future versions, we will display the specific commands undone or redone.
-2. **Feature Flaw** - Currently, using the `copy` command on assets and tags will come with the square brackets associated with the list data structure, which are redundant for the users. In future versions, we will remove these square brackets when copying tags and assets.
-3. **Feature Flaw** - Currently, using the `find` command searches across all contact details, and hence searching `bell` will return contacts with the name including `bell` and contacts with assets including `bell`, which can be confusing. In future versions, we will have specific commands to find contacts and assets separately.
-4. **Feature Flaw** - Currently, additional details cannot be added to assets, such as specifications, locations and so on. In future versions, more details can be added to assets to make the app easier to use for users.
-5. **Feature Flaw** - Currently, using the `add` command for contacts with the same name is not allowed, but there can exist multiple people with the same name. In future versions, we will improve duplicate person detection and allow multiple contacts with the same name.
-6. **Feature Flaw** - Currently, tags and assets have a very similar color scheme, which makes it hard to differentiate for users. In future versions, we will add more visual clarity tags and assets.
-7. **Feature Flaw** - Currently, the error message display for duplicate asset names in the `asset` command is inaccruate to the actual problem. In future versions, we will modify the error message specifically for this case.
+Team size: 5
+
+1. **Make `undo` and `redo` messages more descriptive**: Currently, `undo` and `redo` commands only display a success message without any additional information. In future versions, we will display the specific commands undone or redone, along with the changes.
+2. **Make lists produced by the `copy` command more user-friendly**: Currently, using the `copy` command on assets and tags will include the square brackets associated with the list data structure, which are unnecessary for the users. In future versions, we will remove these square brackets when copying tags and assets.
+3. **Allow searching by specific fields**: Currently, using the `find` command searches across all names, tags, and assets indiscriminately (e.g. searching `bell` may return someone who owns a bell asset and someone else who has the name Bell). We plan to allow users the options to limit the range of their searching either through new commands or specifying prefixes.
+4. **Allow adding of more information to assets**: Currently, additional details cannot be added to assets, such as specifications, locations, etc. In future versions, more details can be added to assets to make the app more useful.
+5. **Provide support for contacts with the same name**: Currently, using the `add` command or `edit` command on names is not allowed if another contact has the same name, but there may exist multiple people with the same name that one needs to keep track of. In future versions, we aim to improve duplicate person detection and potentially allow multiple contacts with the same name as long as other fields are different.
+6. **Add sharper colour contrast between assets and tags**: Currently, tags and assets have a very similar color scheme, making it harder for users to differentiate them. In future versions, we will add more visual clarity tags and assets.
+7. **Make duplicate checking more robust**: The application enforces distinct contacts, but the user may add the same contact twice unintentionally (e.g. entering `dave tan` and `Dave Tan`). We plan to make duplicate checking more robust and potentially warn the user first for such cases.
+8. **Add a `remark` command**: At present users can only add additional information to contacts using tags. We plan to allow the user to add more detailed information like notes using a `remark` command.
+9. **Add command suggestions**: Currently, there is no support for any auto-complete suggestions for commands, that would aid both experienced and new users. We plan to add an auto-complete feature, that would display what command the user is likely typing in a separate pop-up, the ability to press `tab` to quickly complete the command word, and what fields they are missing.
+10. **Make phone number validation more robust**: Currently, we perform little validation on the phone number to allow for inputs such as `2555, 232` for the user's convenience. This however means that inputs such as `+++` would be accepted, which is unlikely to be the user's intention. We plan to improve phone number validation without restricting the user in the future.
diff --git a/docs/_markbind/layouts/default.md b/docs/_markbind/layouts/default.md
index f6b5f7b70b9..c3df79788af 100644
--- a/docs/_markbind/layouts/default.md
+++ b/docs/_markbind/layouts/default.md
@@ -31,11 +31,10 @@
* [Introduction]({{ baseUrl }}/UserGuide.html#introduction)
* [Quick Start]({{ baseUrl }}/UserGuide.html#quick-start)
* [Features]({{ baseUrl }}/UserGuide.html#features)
- * [FAQ]({{ baseUrl }}/UserGuide.html#faq)
- * [Command Summary]({{ baseUrl }}/UserGuide.html#faq)
+ * [FAQ]({{ baseUrl }}/UserGuide.html#frequently-asked-questions)
+ * [Command Summary]({{ baseUrl }}/UserGuide.html#command-summary)
* [Glossary]({{ baseUrl }}/UserGuide.html#glossary)
* [Developer Guide]({{ baseUrl }}/DeveloperGuide.html) :expanded:
- * [Acknowledgements]({{ baseUrl }}/DeveloperGuide.html#acknowledgements)
* [Setting Up]({{ baseUrl }}/DeveloperGuide.html#setting-up-getting-started)
* [Design]({{ baseUrl }}/DeveloperGuide.html#design)
* [Implementation]({{ baseUrl }}/DeveloperGuide.html#implementation)
diff --git a/docs/diagrams/AddSequenceDiagram.puml b/docs/diagrams/AddSequenceDiagram.puml
new file mode 100644
index 00000000000..16fee1569a6
--- /dev/null
+++ b/docs/diagrams/AddSequenceDiagram.puml
@@ -0,0 +1,62 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+skinparam SequenceReferenceBackgroundColor white
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant "command:AddCommand" as AddCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "person:Person" as Person MODEL_COLOR
+participant "assets:Assets" as Assets MODEL_COLOR
+participant "model:Model" as Model MODEL_COLOR
+end box
+
+[-> LogicManager : execute("add ... A\\pen")
+activate LogicManager
+
+LogicManager -> AddressBookParser : parseCommand("add ... A\\pen")
+activate AddressBookParser
+
+' Abstracted factory method call
+AddressBookParser -> AddressBookParser : createCommandUsingFactory("add ... A\\pen")
+note right : createCommandUsingFactory() is the same \n fictitious command as explained in Logic
+activate AddressBookParser
+
+
+create AddCommand
+AddressBookParser -> AddCommand
+activate AddCommand
+
+ref over AddCommand, Person, Assets: create person with assets
+
+AddCommand --> AddressBookParser : command
+deactivate AddCommand
+
+AddressBookParser --> AddressBookParser : command
+deactivate AddressBookParser
+
+AddressBookParser --> LogicManager : command
+deactivate AddressBookParser
+
+LogicManager -> AddCommand : execute(model)
+activate AddCommand
+
+AddCommand -> Model : addPerson(person)
+activate Model
+
+Model --> AddCommand
+deactivate Model
+
+AddCommand --> LogicManager : result
+deactivate AddCommand
+
+AddCommand -[hidden]-> LogicManager
+destroy AddCommand
+
+[<--LogicManager : result
+deactivate LogicManager
+@enduml
diff --git a/docs/diagrams/ArchitectureDiagram.puml b/docs/diagrams/ArchitectureDiagram.puml
index 4c5cf58212e..3bd8ef90275 100644
--- a/docs/diagrams/ArchitectureDiagram.puml
+++ b/docs/diagrams/ArchitectureDiagram.puml
@@ -18,11 +18,11 @@ Class "<$documents>" as File UI_COLOR_T1
UI -[#green]> Logic
-UI -right[#green]-> Model
+UI -[#green]> Model
Logic -[#blue]-> Storage
Logic -down[#blue]-> Model
Main -[#grey]-> UI
-Main -[#grey]-> Logic
+Main .[#grey].> Logic
Main -[#grey]-> Storage
Main -up[#grey]-> Model
Main -down[hidden]-> Commons
diff --git a/docs/diagrams/AssetClassDiagram.puml b/docs/diagrams/AssetClassDiagram.puml
index 8128ec0abde..bf4ef6afb3f 100644
--- a/docs/diagrams/AssetClassDiagram.puml
+++ b/docs/diagrams/AssetClassDiagram.puml
@@ -9,42 +9,26 @@ skinparam classAttributeIconSize 0
show members
-package model {
-
-package asset {
-
+package Model {
class Asset {
- -assetSerial: String
- ==
+ -assetName: String
+ --
+{static} of(String): Asset
}
-}
-
-package person {
-
-class Person {
- -assets: Assets
- ==
-}
-
-package Fields {
+hide empty attributes
+hide empty methods
+class Person
class Assets {
- -assets: Set
- ==
+ --
+{static} of(String[]): Assets
+{static} edit(Asset, Asset): Assets
}
-
-}
-
-}
-
}
-Assets "1..*" *-left- "*" Asset : > contain
+Assets "1" -down-> "*" Asset
-Person o-right- Assets : > has
+Person -right->"1" Assets
@enduml
diff --git a/docs/diagrams/BetterModelClassDiagram.puml b/docs/diagrams/BetterModelClassDiagram.puml
index 598474a5c82..0db7dd0fa1a 100644
--- a/docs/diagrams/BetterModelClassDiagram.puml
+++ b/docs/diagrams/BetterModelClassDiagram.puml
@@ -4,15 +4,18 @@ skinparam arrowThickness 1.1
skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR
-AddressBook *-right-> "1" UniquePersonList
-AddressBook *-right-> "1" UniqueTagList
-UniqueTagList -[hidden]down- UniquePersonList
-UniqueTagList -[hidden]down- UniquePersonList
+AddressBook *-right-> "1" UniquePersonList : ""
+AddressBook -right-> "~*" UniquePersonList : ""
+AddressBook -right-> "~*" UniquePersonList : ""
+AddressBook *-down-> "1" UniqueTagList
+AddressBook *-down-> "1" UniqueAssetList
-UniqueTagList -right-> "*" Tag
-UniquePersonList -right-> Person
+UniqueTagList -down-> "*" Tag
+UniqueAssetList -down-> "*" Asset
+UniquePersonList -down-> Person
Person -up-> "*" Tag
+Person -up-> "*" Asset
Person *--> Name
Person *--> Phone
diff --git a/docs/diagrams/CommandFactorySequenceDiagram.puml b/docs/diagrams/CommandFactorySequenceDiagram.puml
new file mode 100644
index 00000000000..efbe7fbcc46
--- /dev/null
+++ b/docs/diagrams/CommandFactorySequenceDiagram.puml
@@ -0,0 +1,51 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
+participant "<>\nCommandType" as CommandTypeClass LOGIC_COLOR
+participant "type:CommandType" as CommandType LOGIC_COLOR
+participant "<>\nDeleteCommand" as DeleteCommandClass LOGIC_COLOR
+participant "command:DeleteCommand" as DeleteCommand LOGIC_COLOR
+end box
+
+[-> AddressBookParser : parseCommand("delete 1")
+activate AddressBookParser
+
+AddressBookParser -> CommandTypeClass : valueOf("DELETE")
+activate CommandTypeClass
+
+create CommandType
+CommandTypeClass -> CommandType
+activate CommandType
+
+CommandType -> CommandTypeClass : type
+deactivate CommandType
+
+CommandTypeClass -> AddressBookParser : type
+deactivate CommandTypeClass
+
+AddressBookParser -> CommandType : createCommand(" 1")
+activate CommandType
+
+CommandType -> DeleteCommandClass : of(" 1")
+activate DeleteCommandClass
+
+create DeleteCommand
+DeleteCommandClass -> DeleteCommand
+activate DeleteCommand
+
+DeleteCommand --> DeleteCommandClass : command
+deactivate DeleteCommand
+
+DeleteCommandClass --> CommandType : command
+deactivate DeleteCommandClass
+
+CommandType --> AddressBookParser : command
+deactivate CommandType
+
+[<-- AddressBookParser : command
+deactivate AddressBookParser
+
+@enduml
diff --git a/docs/diagrams/CommandHistoryAddSequenceDiagram.puml b/docs/diagrams/CommandHistoryAddSequenceDiagram.puml
new file mode 100644
index 00000000000..ab12348e891
--- /dev/null
+++ b/docs/diagrams/CommandHistoryAddSequenceDiagram.puml
@@ -0,0 +1,22 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":CommandHistory" as CommandHistory LOGIC_COLOR
+end box
+
+-> LogicManager : execute(commandText)
+activate LogicManager
+
+LogicManager -> CommandHistory : add(commandText)
+activate CommandHistory
+
+CommandHistory --> LogicManager
+deactivate CommandHistory
+
+<-- LogicManager : commandResult
+deactivate LogicManager
+
+@enduml
diff --git a/docs/diagrams/CommandHistoryUpSequenceDiagram.puml b/docs/diagrams/CommandHistoryUpSequenceDiagram.puml
new file mode 100644
index 00000000000..49e2d1035f3
--- /dev/null
+++ b/docs/diagrams/CommandHistoryUpSequenceDiagram.puml
@@ -0,0 +1,41 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box UI UI_COLOR_T1
+participant ":CommandBox" as CommandBox UI_COLOR
+participant ":RecordedCommandExecutor" as RecordedCommandExecutor UI_COLOR
+end box
+
+box Logic LOGIC_COLOR_T1
+participant ":LogicManager" as LogicManager LOGIC_COLOR
+participant ":CommandHistory" as CommandHistory LOGIC_COLOR
+end box
+
+-> CommandBox : handleKeyPressed(event)
+activate CommandBox
+
+CommandBox -> RecordedCommandExecutor : getPreviousCommandText()
+activate RecordedCommandExecutor
+
+RecordedCommandExecutor -> LogicManager : getPreviousCommandText()
+activate LogicManager
+
+LogicManager -> CommandHistory : getPrevious()
+activate CommandHistory
+
+CommandHistory --> LogicManager : commandText
+deactivate CommandHistory
+
+LogicManager --> RecordedCommandExecutor : commandText
+deactivate LogicManager
+
+RecordedCommandExecutor --> CommandBox : commandText
+deactivate RecordedCommandExecutor
+
+CommandBox -> CommandBox : setText(commandText)
+note right : CommandBox#setText() is a\nfictitious command to improve brevity
+<-- CommandBox
+deactivate CommandBox
+
+@enduml
diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml
index e2e38a8311a..fff7870f9a7 100644
--- a/docs/diagrams/DeleteSequenceDiagram.puml
+++ b/docs/diagrams/DeleteSequenceDiagram.puml
@@ -5,12 +5,11 @@ skinparam ArrowFontStyle plain
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
-participant "<>\nDeleteCommand" as DeleteCommandClass LOGIC_COLOR
-participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR
+participant "command:DeleteCommand" as DeleteCommand LOGIC_COLOR
end box
box Model MODEL_COLOR_T1
-participant "m:Model" as Model MODEL_COLOR
+participant "model:Model" as Model MODEL_COLOR
end box
[-> LogicManager : execute("delete 1")
@@ -21,23 +20,23 @@ activate AddressBookParser
' Abstracted factory method call
AddressBookParser -> AddressBookParser : createCommandUsingFactory("delete 1")
-activate AddressBookParser #FFBBBB
-note right: createCommandUsingFactory() is a simplified representation of the command creation process.
+note right: createCommandUsingFactory() is a fictitious command \n representing the command creation process for brevity
+activate AddressBookParser
create DeleteCommand
-AddressBookParser -> DeleteCommand : new("1")
+AddressBookParser -> DeleteCommand
activate DeleteCommand
-DeleteCommand --> AddressBookParser
+DeleteCommand --> AddressBookParser : command
deactivate DeleteCommand
-AddressBookParser --> AddressBookParser
-deactivate AddressBookParser #FFBBBB
+AddressBookParser --> AddressBookParser : command
+deactivate AddressBookParser
-AddressBookParser --> LogicManager : d
+AddressBookParser --> LogicManager : command
deactivate AddressBookParser
-LogicManager -> DeleteCommand : execute(m)
+LogicManager -> DeleteCommand : execute(model)
activate DeleteCommand
DeleteCommand -> Model : deletePerson(1)
@@ -49,6 +48,9 @@ deactivate Model
DeleteCommand --> LogicManager : result
deactivate DeleteCommand
-[<--LogicManager
+DeleteCommand -[hidden]-> LogicManager
+destroy DeleteCommand
+
+[<--LogicManager : result
deactivate LogicManager
@enduml
diff --git a/docs/diagrams/FindSequenceDiagram.puml b/docs/diagrams/FindSequenceDiagram.puml
deleted file mode 100644
index 3ee21b3cb8e..00000000000
--- a/docs/diagrams/FindSequenceDiagram.puml
+++ /dev/null
@@ -1,82 +0,0 @@
-@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 "<>\nCommandType" as CommandTypeClass LOGIC_COLOR
-participant "commandType:CommandType" as CommandType LOGIC_COLOR
-participant "<>\nFindCommand" as FindCommandClass LOGIC_COLOR
-participant "command:FindCommand" as FindCommand LOGIC_COLOR
-end box
-
-box Model MODEL_COLOR_T1
-participant "predicate:PersonMatchesKeywordsPredicate" as PersonMatchesKeywordsPredicate MODEL_COLOR
-participant "model:Model" as Model MODEL_COLOR
-end box
-
-[-> LogicManager : execute("find David")
-activate LogicManager
-
-LogicManager -> AddressBookParser : parseCommand("find David")
-activate AddressBookParser
-
-AddressBookParser -> CommandTypeClass : valueOf("FIND")
-activate CommandTypeClass
-
-create CommandType
-CommandTypeClass -> CommandType
-activate CommandType
-
-CommandType --> CommandTypeClass : commandType
-deactivate CommandType
-
-CommandTypeClass --> AddressBookParser : commandType
-deactivate CommandTypeClass
-
-AddressBookParser -> CommandType : createCommand(" David")
-activate CommandType
-
-CommandType -> FindCommandClass : of(" David")
-activate FindCommandClass
-
-create PersonMatchesKeywordsPredicate
-FindCommandClass -> PersonMatchesKeywordsPredicate : PersonMatchesKeywordsPredicate(["David"])
-activate PersonMatchesKeywordsPredicate
-
-PersonMatchesKeywordsPredicate --> FindCommandClass : predicate
-deactivate PersonMatchesKeywordsPredicate
-
-create FindCommand
-FindCommandClass -> FindCommand : FindCommand(predicate)
-activate FindCommand
-
-FindCommand --> FindCommandClass : command
-deactivate FindCommand
-
-FindCommandClass --> CommandType : command
-deactivate FindCommandClass
-
-CommandType --> AddressBookParser : command
-deactivate CommandType
-
-AddressBookParser --> LogicManager : command
-deactivate AddressBookParser
-
-
-LogicManager -> FindCommand : execute(model)
-activate FindCommand
-
-FindCommand -> Model : updateFilteredPersonList(predicate)
-activate Model
-
-Model --> FindCommand
-deactivate Model
-
-FindCommand --> LogicManager : commandResult
-deactivate FindCommand
-
-[<--LogicManager : commandResult
-deactivate LogicManager
-@enduml
diff --git a/docs/diagrams/FindSequenceDiagram1.puml b/docs/diagrams/FindSequenceDiagram1.puml
new file mode 100644
index 00000000000..34eb9ef11c6
--- /dev/null
+++ b/docs/diagrams/FindSequenceDiagram1.puml
@@ -0,0 +1,34 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant "<>\nFindCommand" as FindCommandClass LOGIC_COLOR
+participant "command:FindCommand" as FindCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "predicate:PersonMatchesQueryPredicate" as PersonMatchesQueryPredicate MODEL_COLOR
+end box
+
+-> FindCommandClass : of(" David")
+activate FindCommandClass
+
+create PersonMatchesQueryPredicate
+FindCommandClass -> PersonMatchesQueryPredicate : PersonMatchesQueryPredicate("David")
+activate PersonMatchesQueryPredicate
+
+PersonMatchesQueryPredicate --> FindCommandClass : predicate
+deactivate PersonMatchesQueryPredicate
+
+create FindCommand
+FindCommandClass -> FindCommand : FindCommand(predicate)
+activate FindCommand
+
+FindCommand --> FindCommandClass : command
+deactivate FindCommand
+
+<-- FindCommandClass : command
+deactivate FindCommandClass
+
+@enduml
diff --git a/docs/diagrams/FindSequenceDiagram2.puml b/docs/diagrams/FindSequenceDiagram2.puml
new file mode 100644
index 00000000000..eb57d4a548e
--- /dev/null
+++ b/docs/diagrams/FindSequenceDiagram2.puml
@@ -0,0 +1,28 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+
+box Logic LOGIC_COLOR_T1
+participant "command:FindCommand" as FindCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "model:Model" as Model MODEL_COLOR
+end box
+
+-> FindCommand : execute(model)
+activate FindCommand
+
+FindCommand -> Model : updateFilteredPersonList(predicate)
+activate Model
+
+Model --> FindCommand
+deactivate Model
+
+<-- FindCommand : result
+deactivate FindCommand
+
+<-[hidden]- FindCommand
+destroy FindCommand
+
+@enduml
diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml
index 3c265d2e065..fb7d17d9a50 100644
--- a/docs/diagrams/LogicClassDiagram.puml
+++ b/docs/diagrams/LogicClassDiagram.puml
@@ -8,11 +8,10 @@ package Logic as LogicPackage {
Class AddressBookParser
-Class CommandType
+Class "<>\nCommandType" as CommandType
Class XYZCommand
Class "{abstract}\nCommand" as Command
-
-
+Class CommandHistory
Class "<>\nLogic" as Logic
Class LogicManager
@@ -22,7 +21,6 @@ Class ParserUtil
}
package Model {
-Class HiddenModel #FFFFFF
}
package Storage {
@@ -31,24 +29,27 @@ package Storage {
Class HiddenOutside #FFFFFF
HiddenOutside ..> Logic
-LogicManager .left.|> Logic
-LogicManager -->"1" AddressBookParser
+LogicManager .up.|> Logic
+LogicManager ..> AddressBookParser : parses with >
+LogicManager .down.> Command : executes >
+LogicManager -left-> CommandHistory
AddressBookParser ..> CommandType : uses >
CommandType .right.> XYZCommand : creates >
XYZCommand -up-|> Command
-LogicManager ..> Command : executes >
LogicManager --> Model
LogicManager -right-> Storage
Command .right.> Model
-note right of XYZCommand: XYZCommand = AddCommand, \nFindCommand, etc
XYZCommand ..> ArgumentMultimap
XYZCommand ..> ArgumentTokenizer
XYZCommand ..> ParserUtil
ArgumentTokenizer .left.> ArgumentMultimap
+
+ArgumentMultimap --> Model
+ArgumentTokenizer ..> Model
@enduml
diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml
index 805aa9297c7..ad4ffa24925 100644
--- a/docs/diagrams/ModelClassDiagram.puml
+++ b/docs/diagrams/ModelClassDiagram.puml
@@ -37,9 +37,12 @@ Model .right.> ReadOnlyUserPrefs
Model .left.> ReadOnlyAddressBook
ModelManager -left-> "1" AddressBook
ModelManager -right-> "1" UserPrefs
+ModelManager ..> Asset
UserPrefs .up.|> ReadOnlyUserPrefs
-AddressBook *--> "1" UniquePersonList
+AddressBook *--> "persons 1" UniquePersonList
+AddressBook --> "~*" UniquePersonList : tracks\nundo\nwith >
+AddressBook --> "~*" UniquePersonList : tracks\nredo\nwith >
UniquePersonList --> "~* all" Person
Person *--> Name
Person *--> Phone
diff --git a/docs/diagrams/PersonWithAssetsSequenceDiagram.puml b/docs/diagrams/PersonWithAssetsSequenceDiagram.puml
new file mode 100644
index 00000000000..7eae239f340
--- /dev/null
+++ b/docs/diagrams/PersonWithAssetsSequenceDiagram.puml
@@ -0,0 +1,43 @@
+@startuml
+!include style.puml
+skinparam ArrowFontStyle plain
+skinparam SequenceGroupBodyBackgroundColor MODEL_COLOR_T1
+
+box Logic LOGIC_COLOR_T1
+participant "command:AddCommand" as AddCommand LOGIC_COLOR
+end box
+
+box Model MODEL_COLOR_T1
+participant "person:Person" as Person MODEL_COLOR
+participant "assets:Assets" as Assets MODEL_COLOR
+end box
+
+mainframe **sd** create person with assets
+
+create Person
+AddCommand -> Person
+note right: Note that Person and Assets also use factory \n methods, but it is not shown here for brevity
+activate Person
+
+create Assets
+Person -> Assets
+activate Assets
+
+note right Assets: Assets may call the constructor of Asset zero or more \n times depending on the input, represented here by a \n fictitious method createAssetObjects()
+loop until all assets created
+Assets -> Assets : createAssetObject()
+activate Assets
+
+Assets --> Assets
+deactivate Assets
+
+Assets -[hidden]-> Assets
+end
+
+Assets --> Person : assets
+deactivate Assets
+
+Person --> AddCommand : person
+deactivate Person
+
+@enduml
diff --git a/docs/diagrams/StorageClassDiagram.puml b/docs/diagrams/StorageClassDiagram.puml
index 2ce9f104b89..720901d0d36 100644
--- a/docs/diagrams/StorageClassDiagram.puml
+++ b/docs/diagrams/StorageClassDiagram.puml
@@ -4,6 +4,9 @@ skinparam arrowThickness 1.1
skinparam arrowColor STORAGE_COLOR
skinparam classBackgroundColor STORAGE_COLOR
+package Model {
+}
+
package Storage as StoragePackage {
package "UserPrefs Storage" #F4F6F6{
@@ -34,4 +37,8 @@ Storage -right-|> AddressBookStorage
JsonUserPrefsStorage .up.|> UserPrefsStorage
JsonAddressBookStorage .up.|> AddressBookStorage
+JsonAddressBookStorage ..> Model
+StorageManager ..> Model
+JsonUserPrefsStorage ..> Model
+
@enduml
diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml
index 95473d5aa19..cd1b46e793a 100644
--- a/docs/diagrams/UiClassDiagram.puml
+++ b/docs/diagrams/UiClassDiagram.puml
@@ -34,7 +34,7 @@ MainWindow *-down-> "1" CommandBox
MainWindow *-down-> "1" ResultDisplay
MainWindow *-down-> "1" PersonListPanel
MainWindow *-down-> "1" StatusBarFooter
-MainWindow --> "0..1" HelpWindow
+MainWindow --> "1" HelpWindow
PersonListPanel -down-> "*" PersonCard
@@ -47,7 +47,7 @@ PersonCard --|> UiPart
StatusBarFooter --|> UiPart
HelpWindow --|> UiPart
-PersonCard ..> Model
+PersonCard --> Model
UiManager -right-> Logic
MainWindow -left-> Logic
diff --git a/docs/diagrams/UndoSequenceDiagram-Logic.puml b/docs/diagrams/UndoSequenceDiagram-Logic.puml
index 4cfa2f01768..b86b0e82b5e 100644
--- a/docs/diagrams/UndoSequenceDiagram-Logic.puml
+++ b/docs/diagrams/UndoSequenceDiagram-Logic.puml
@@ -5,7 +5,7 @@ skinparam ArrowFontStyle plain
box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
-participant "u:UndoCommand" as UndoCommand LOGIC_COLOR
+participant "command:UndoCommand" as UndoCommand LOGIC_COLOR
end box
box Model MODEL_COLOR_T1
@@ -17,17 +17,25 @@ activate LogicManager
LogicManager -> AddressBookParser : parseCommand("undo")
activate AddressBookParser
+' Abstracted factory method call
+AddressBookParser -> AddressBookParser : createCommandUsingFactory("undo")
+note right: createCommandUsingFactory() is a fictitious command \n representing the command creation process for brevity
+activate AddressBookParser
+
create UndoCommand
AddressBookParser -> UndoCommand
activate UndoCommand
-UndoCommand --> AddressBookParser
+UndoCommand --> AddressBookParser : command
deactivate UndoCommand
-AddressBookParser --> LogicManager : u
+AddressBookParser --> AddressBookParser : command
+deactivate AddressBookParser
+
+AddressBookParser --> LogicManager : command
deactivate AddressBookParser
-LogicManager -> UndoCommand : execute(m)
+LogicManager -> UndoCommand : execute(model)
activate UndoCommand
UndoCommand -> Model : undo()
@@ -38,9 +46,9 @@ deactivate Model
UndoCommand --> LogicManager : result
deactivate UndoCommand
-UndoCommand -[hidden]-> LogicManager : result
+UndoCommand -[hidden]-> LogicManager
destroy UndoCommand
-[<--LogicManager
+[<--LogicManager : result
deactivate LogicManager
@enduml
diff --git a/docs/diagrams/UndoSequenceDiagram-Model.puml b/docs/diagrams/UndoSequenceDiagram-Model.puml
index a0157b7fef1..784f509d517 100644
--- a/docs/diagrams/UndoSequenceDiagram-Model.puml
+++ b/docs/diagrams/UndoSequenceDiagram-Model.puml
@@ -14,9 +14,15 @@ activate Model
Model -> AddressBook : undo()
activate AddressBook
-AddressBook -> AddressBook :savePersonsTo(redoStack)
+AddressBook -> AddressBook : savePersonsTo(redoStack)
-AddressBook -> persons : setPersons(personFromUndoStack)
+AddressBook -> AddressBook : getPersonsFrom(undoStack)
+activate AddressBook
+note right : getPersonsFrom() is a fictitious\ncommand to improve readability.\nIt is simply a stack.pop()\nmethod implementation-wise.
+AddressBook --> AddressBook : p
+deactivate AddressBook
+
+AddressBook -> persons : setPersons(p)
activate persons
persons --> AddressBook
deactivate persons
diff --git a/docs/diagrams/style.puml b/docs/diagrams/style.puml
index f7d7347ae84..9377829e656 100644
--- a/docs/diagrams/style.puml
+++ b/docs/diagrams/style.puml
@@ -31,6 +31,9 @@
!define STORAGE_COLOR_T3 #806600
!define STORAGE_COLOR_T2 #544400
+!define JAVAFX_COLOR #E76F00
+!define JAVAFX_COLOR_T1 #DEB38C
+
!define USER_COLOR #000000
skinparam Package {