diff --git a/docs/Configuration.md b/docs/Configuration.md index 32f6255f3b9..f4c3b04362b 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -5,4 +5,4 @@ # Configuration guide -Certain properties of the application can be controlled (e.g user preferences file location, logging level) through the configuration file (default: `config.json`). +Certain properties of the application can be controlled (e.g. user preferences file location, logging level) through the configuration file (default: `config.json`). diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 3f399598ce1..788aa3f0891 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -11,12 +11,6 @@ -------------------------------------------------------------------------------------------------------------------- -## **Acknowledgements** - -_{ list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well }_ - --------------------------------------------------------------------------------------------------------------------- - ## **Setting up, getting started** Refer to the guide [_Setting up and getting started_](SettingUp.md). @@ -25,6 +19,12 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md). ## **Design** + + +**Note:** The lifeline for *Commands* in all Sequence Diagrams should end at the destroy marker (X) if they exist, but due to a limitation of PlantUML, the lifeline reaches the end of diagram. + + + ### Architecture @@ -35,7 +35,7 @@ Given below is a quick overview of main components and how they interact with ea **Main components of the architecture** -**`Main`** (consisting of classes [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java)) is in charge of the app launch and shut down. +**`Main`** (consisting of classes [`Main`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/MainApp.java)) is in charge of the app launch and shut down. * At app launch, it initializes the other components in the correct sequence, and connects them up with each other. * At shut down, it shuts down the other components and invokes cleanup methods where necessary. @@ -67,13 +67,13 @@ The sections below give more details of each component. ### UI component -The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java) +The **API** of this component is specified in [`Ui.java`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/ui/Ui.java) - + The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI. -The `UI` component uses the JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/resources/view/MainWindow.fxml) +The `UI` component uses the JavaFX UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the [`MainWindow`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/resources/view/MainWindow.fxml) The `UI` component, @@ -84,20 +84,36 @@ The `UI` component, ### Logic component -**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java) +**API** : [`Logic.java`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/logic/Logic.java) Here's a (partial) class diagram of the `Logic` component: + + +**Note:** +* `XYZCommand` refers to all `Command` classes i.e. `AddCommand`, `FindCommand`, etc. +* Not all `Command` classes utilize `ArgumentMultimap`, `ArgumentTokenizer` or `ParserUtil` classes. + + + +--- + The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example. - + + +All `Command` objects are created via the enum factory pattern. The following sequence diagram expands on the actual command +creation process encapsulated by `createCommandUsingFactory()` in the above diagram. +Note that the leading whitespace in `" 1"` is an implementation detail of `AddressBookParser`. + + How the `Logic` component works: -1. When `Logic` is called upon to execute a command, it is passed to an `AddressBookParser` object which in turn uses an enum factory `CommandType` to create the relevant enum (e.g. `CommandType.DELETE`) with the input arguments. -1. The `CommandType` enum calls the relevant command's factory method to create a command object (e.g. `DeleteCommand`). +1. When `Logic` is called upon to execute a command, it is passed to an `AddressBookParser` object which in turn uses an enum factory `CommandType` to create the relevant enum (e.g. `CommandType.DELETE`) from the parsed command word. +1. The `CommandType` enum calls the relevant command's factory method to create a command object (e.g. `DeleteCommand`) with the parsed arguments. 1. The command can communicate with the `Model` when it is executed (e.g. to delete a person).
Note that although this is shown as a single step in the diagram above (for simplicity), in the code it can take several interactions (between the command object and the `Model`) to achieve. 1. The result of the command execution is returned back from `Logic` as a `String`. @@ -109,21 +125,28 @@ How the parsing works: 3. The command object (e.g. `DeleteCommand`) uses `ArgumentTokenizer`, `ArgumentMultimap` and possibly `ParserUtil` to break down and interpret the user input arguments. ### Model component -**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java) +**API** : [`Model.java`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/model/Model.java) The `Model` component, -* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object). -* stores the currently 'selected' `Person` objects (e.g., results of a search query) as a separate _filtered_ list which is exposed to outsiders as an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. +* stores the address book data i.e. all `Person` objects (which are contained in a `UniquePersonList` object). +* stores the currently 'selected' `Person` objects (e.g. results of a search query) as a separate _filtered_ list which is exposed to outsiders as an unmodifiable `ObservableList` that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. +* stores previous states of the `UniquePersonList` in a private `undoStack`. +* stores previously undone states of the `UniquePersonList` in a private `redoStack`. * stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects. * does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other components) + -**Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Person` needing their own `Tag` objects.
+**Note:** + +* More details on the implementation of `undo` and `redo` can be found [here](#undo-redo-feature). + +* An alternative (arguably, more OOP) model is given below. It has a `Tag` list and an `Asset` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, and one `Asset` object per unique asset, instead of each `Person` needing their own `Tag` and `Asset` objects.
@@ -132,7 +155,7 @@ The `Model` component, ### Storage component -**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java) +**API** : [`Storage.java`](https://github.com/AY2324S2-CS2103T-W12-3/tp/blob/master/src/main/java/seedu/address/storage/Storage.java) @@ -143,7 +166,7 @@ The `Storage` component, ### Common classes -Classes used by multiple components are in the `seedu.addressbook.commons` package. +Some classes used by multiple components are in the `seedu.addressbook.commons` package. -------------------------------------------------------------------------------------------------------------------- @@ -153,36 +176,60 @@ This section describes some noteworthy details on how certain features are imple ### Asset feature -Asset related functionality is supported by an `Asset` and `Assets` objects. +Asset related functionality is supported by `Asset` and `Assets` objects. `Assets` are the actual field belonging to +a `Person` object, and may contain zero or more `Asset` objects. -The following class diagram details the relationship between classes involved under the model package. +The following class diagram details the relationship between classes involved under the model component. - + `Assets` and `Asset` objects are immutable and expose a static factory `of` method which parses `String` objects to -return the respective class. The `Assets` class has a static `edit` method which facilitates creating a new `Assets` -object with a specified `Asset` object replaced. +return the respective class. To support editing a `Person` object's `Assets`, the `Assets` class has a static `edit` +method which facilitates creating a new `Assets` object with a specified `Asset` object replaced. Assets are created when the user invokes the `add`, `edit` or `asset` commands specifying an asset is to be associated with person. +The following sequence diagram shows how an `add` command specifying creating a contact responsible for a 'pen' +asset interacts with the classes in `Logic` and `Model`. + + + +The follow sequence diagram expands on the process of creating a person with assets referenced in the above diagram. + + + +The edit asset mechanism is implemented by the following operations: + +1. Search through the entire `persons` list. +2. Look through the `assets` list of each `person`. +3. If the `assetName` is equivalent to the name from the `o\` prefix, rename it to the `assetName` specified by the `n\` prefix. If the `assetName` does not match, do nothing. + +**Note:** If the `assetName` specified by the `o\` prefix does not exist in the user input, the application will throw an error to inform the user that the command is invalid. + #### Design Considerations **Aspect: How users create and update assets** -* **Alternative 1 (selected choice)**: The user specifies only the serial no. of the asset in `add`. +* **Alternative 1**: The user specifies only the serial no. of the asset in `add`. The user uses the `asset` command to add or edit details to each asset. * Pros: * Each asset is unambiguously and uniquely identified on creation. * The user cannot make mistakes such as creating the same asset twice with different details. * Cons: * The user must use two separate commands to add an asset with details. -* **Alternative 2**: The user specifies all details of the asset in `add`. + + +* **Alternative 2 (selected choice)**: The user specifies all details of the asset in `add`. Assets only have a name. * Pros: * Advanced users save time as only a single command is required to specify all details of multiple assets. + * There is no possibility of data inconsistency. * Cons: - * There is a lot of room for users to make mistakes such as creating the same asset twice with different details. + * There is a lot of room for users to make mistakes such as creating the same asset twice unintentionally. This leads to the need to decide how best to handle each error. Throwing errors may frustrate the user while making a guess of the user's intention may result in unintended changes made to the contacts. + * The onus is on the user to uniquely name similar but distinct assets. + + * **Alternative 3**: Have a dedicated set of commands to create and edit assets. * Pros: * The person related commands are not overloaded with the functionality to control assets. @@ -190,8 +237,18 @@ associated with person. * Cons: * Harder to implement, a second set of commands is essentially required. * Not the focus of the application, which is contact management. + + +* **Alternative 4**: Repurpose the existing tags feature as assets. + * Pros: + * Little implementation work and lower chance of bugs. + * Less clutter in information presented to the user. + * Cons: + * Limited flexibility in extending the feature. + * Users lose the ability to tag contacts which is a natural feature to have. + -**Aspect: How asset update is implemented** +**Aspect: How updating of assets is implemented** * **Alternative 1 (selected choice)**: All `Assets` and `Asset` objects are immutable; a linear search and replace is performed to update the `UniquePersonList` whenever a change to any is required. * Pros: @@ -201,34 +258,28 @@ associated with person. proportion is already invested in saving after each operation, so this extra time per operation is not as significant. * More likely to have data inconsistency bugs. + + * **Alternative 2**: `Asset` has a static hash table with some primary key. * Pros: * All persons sharing an asset will have it represented by the same object in memory, making it easy to update. * Less likelihood of data inconsistency bugs. * Cons: * This design is not immutable, meaning undo is excessively difficult to implement. + ### Find feature -The following sequence diagram shows how a `find David` command is executed. - - -

- -### Edit Asset feature +The `PersonMatchesQueryPredicate` class defines the algorithm that determines whether a `Person` matches the user's `query` string. -The following sequence diagram shows how a `edita old/Aircon new/Hammer` command is executed. +The following sequence diagram shows how the `command` object is created when the user executes `find David`. Note that the leading whitespace in `" David"` is an implementation detail of `AddressBookParser`. - +

-The edit asset mechanism is implemented by the following operations: - -1. Search through the entire `persons` list. -2. Look through the `asset` list in each `person`. -3. If the `asset` name names the `asset` name in the `old/` prefix, then change it to the `asset` name specified in the `new/` prefix. If the `asset` name does not match, do nothing. - -**Note:** If the `asset` name specified in the `old/` prefix does not exist within the application, the application will throw an error to inform the user that the command is invalid. +The _filtered_ list of `Person` objects in `model` is then updated as such: + +

### Undo/Redo feature @@ -246,19 +297,19 @@ Given below is an example usage scenario and how the undo/redo mechanism behaves Step 1. The user launches the application for the first time. The `persons` list will be initialized with the initial address book state (State 0), with the `undoStack` and `redoStack` empty. - + -Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls several other functions until it calls `save()`. This causes the state of the `persons` list **before** the `delete 5` command is executed (State 0) to be saved into the `undoStack`. The 5th person is then removed from the `persons` list (State 1). +Step 2. The user executes the command `delete 5` to delete the 5th person in the address book. The `delete` command eventually calls `save()`, which causes the state of the `persons` list **before** `delete 5` is executed (State 0) to be saved into the `undoStack`. The 5th person is then removed from the `persons` list (State 1). - + -Step 3. The user executes `add n/David ...` to add a new person. The `add` command also calls `save()`, causing another `persons` list state (State 1) to be saved into the `undoStack`, before adding the person (State 2). +Step 3. The user executes `add n/David ...` to add a new person. The `add` command eventually calls `save()`, causing another `persons` list state (State 1) to be saved into the `undoStack`, before adding the person (State 2). - + -**Note:** If a command fails its execution, or if the command does not modify `persons` list, it will not call `save()`, so the `persons` list state will not be saved into the `undoStack`. +**Note:** If a command fails its execution, or if the command does not modify the `persons` list, it will not call `save()`. Hence, this `persons` list state will not be saved into the `undoStack`. @@ -269,7 +320,7 @@ Step 4. The user now decides that adding the person was a mistake, and decides t Notice that the states are copied into the `persons` list instead of replacing it, resulting in the exact same object being used. This is to prevent synchronization issues and to reduce coupling with the GUI, allowing the GUI to use this same list object throughout the program's life. - + @@ -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 {