From 2a319e4010d92d8aeb072ae6ac9a44bf65cade7b Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 07:48:08 +0800 Subject: [PATCH 1/7] Update UML for undo command --- docs/diagrams/UndoSequenceDiagram-Model.puml | 24 +++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/diagrams/UndoSequenceDiagram-Model.puml b/docs/diagrams/UndoSequenceDiagram-Model.puml index d354857777b..643585d0ccf 100644 --- a/docs/diagrams/UndoSequenceDiagram-Model.puml +++ b/docs/diagrams/UndoSequenceDiagram-Model.puml @@ -4,19 +4,37 @@ skinparam ArrowFontStyle plain box Model MODEL_COLOR_T1 participant ":Model" as Model MODEL_COLOR +participant ":CampusConnect" as CampusConnect MODEL_COLOR participant ":VersionedCampusConnect" as VersionedCampusConnect MODEL_COLOR end box [-> Model : undoCampusConnect() activate Model -Model -> VersionedCampusConnect : undo() +Model -> CampusConnect: recoverPreviousState() +activate CampusConnect + +CampusConnect -> VersionedCampusConnect: extractOldData() +activate VersionedCampusConnect + +VersionedCampusConnect -> VersionedCampusConnect: saveCurrentData() activate VersionedCampusConnect -VersionedCampusConnect -> VersionedCampusConnect :resetData(ReadOnlyCampusConnect) -VersionedCampusConnect --> Model : +VersionedCampusConnect --> VersionedCampusConnect +deactivate VersionedCampusConnect + +VersionedCampusConnect --> CampusConnect: deactivate VersionedCampusConnect +CampusConnect --> Model: cc +deactivate CampusConnect + +Model -> Model: setCampusConnect(cc) +activate Model + +Model --> Model +deactivate Model + [<-- Model deactivate Model From 724d296d6e02e6519fd3c36da042cde24b440b22 Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 08:12:11 +0800 Subject: [PATCH 2/7] Correct bugs in UndoCommand --- docs/diagrams/CommitActivityDiagram.puml | 14 ++++++++++---- .../java/seedu/address/logic/LogicManager.java | 2 +- .../java/seedu/address/model/CampusConnect.java | 4 ++++ src/main/java/seedu/address/model/Model.java | 11 ++++++++--- .../java/seedu/address/model/ModelManager.java | 6 ++++++ 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/docs/diagrams/CommitActivityDiagram.puml b/docs/diagrams/CommitActivityDiagram.puml index 3823313f3ae..b0f1a5bdb41 100644 --- a/docs/diagrams/CommitActivityDiagram.puml +++ b/docs/diagrams/CommitActivityDiagram.puml @@ -8,10 +8,16 @@ start 'Since the beta syntax does not support placing the condition outside the 'diamond we place it as the true branch instead. -if () then ([command commits CampusConnect]) - :Purge redundant states; - :Save CampusConnect to - campusConnectStateList; +if () then ([command modifies CampusConnect]) + :Purge undone states in the + "future" stack; + :Save current CampusConnect + to "history" stack; + if () then ([command execution fails]) + : Undo old version of + CampusConnect; + else ([else]) + endif else ([else]) endif stop diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index 3ef09d090c8..190e01ad267 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -62,7 +62,7 @@ public CommandResult execute(String commandText) throws CommandException, ParseE storage.saveCampusConnect(model.getCampusConnect()); } catch (CommandException e) { if (!(command instanceof RedoCommand)) { - model.undoCampusConnect(); + model.undoExceptionalCommand(); } throw e; } catch (AccessDeniedException e) { diff --git a/src/main/java/seedu/address/model/CampusConnect.java b/src/main/java/seedu/address/model/CampusConnect.java index 19883570746..1281e705421 100644 --- a/src/main/java/seedu/address/model/CampusConnect.java +++ b/src/main/java/seedu/address/model/CampusConnect.java @@ -77,6 +77,10 @@ public ReadOnlyCampusConnect recoverUndoneState() throws RedoException { return out; } + public ReadOnlyCampusConnect recoverStateWithoutSaving() throws UndoException { + return versionedCampusConnect.extractOldData(); + } + /** * Replaces the contents of the person list with {@code persons}. * {@code persons} must not contain duplicate persons. diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 6805d5d5bda..6ae2d53299f 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -131,17 +131,22 @@ public interface Model { void updateFilteredPersonList(Predicate predicate); /** - * Undo the previous actions of users + * Undoes the previous actions of users */ void undoCampusConnect() throws CommandException; /** - * Restore state before previous undo actions of users + * Restores state before previous undo actions of users */ void redoCampusConnect() throws CommandException; /** - * Save current state of model before execution. + * Saves current state of model before execution. */ void saveCurrentCampusConnect(); + + /** + * Undoes a state without saving current state when execution fails. + */ + void undoExceptionalCommand() throws CommandException; } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index cfe97f349c4..748fd20f670 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -231,5 +231,11 @@ public void redoCampusConnect() throws CommandException { public void saveCurrentCampusConnect() { campusConnect.saveCurrentState(); } + + @Override + public void undoExceptionalCommand() throws CommandException { + ReadOnlyCampusConnect cc = campusConnect.recoverStateWithoutSaving(); + this.setCampusConnect(cc); + } } From c3e9feac57922397795e5c603c9ae6daa4c9450e Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 08:15:06 +0800 Subject: [PATCH 3/7] Update model stub --- .../java/seedu/address/logic/commands/AddCommandTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index 32d36fa5991..4a15e38be15 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -214,6 +214,11 @@ public void setTagsCategory(Tag t, TagCategory cat) { public TagCategory getTagCategory(Tag t) { throw new AssertionError("This method should not be called"); } + + @Override + public void undoExceptionalCommand() { + throw new AssertionError("This method should not be called"); + } } /** From cda21111708738ccc75d481520ab47f867a3caac Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 08:22:09 +0800 Subject: [PATCH 4/7] Modify DG --- docs/DeveloperGuide.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4f40a67e138..ef5405bac2d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -134,7 +134,7 @@ The structure is simple: The `Model` component, -* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object). +* stores the CampusConnect 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 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) @@ -155,7 +155,7 @@ The `Model` component, The `Storage` component, -* can save both address book data and user preference data in JSON format, and read them back into corresponding objects. +* can save both CampusConnect data and user preference data in JSON format, and read them back into corresponding objects. * inherits from both `CampusConnectStorage` and `UserPrefStorage`, which means it can be treated as either one (if only the functionality of only one is needed). * depends on some classes in the `Model` component (because the `Storage` component's job is to save/retrieve objects that belong to the `Model`) @@ -169,16 +169,16 @@ Classes used by multiple components are in the `seedu.address.commons` package. This section describes some noteworthy details on how certain features are implemented. -### \[Proposed\] Undo/redo feature +### Undo/redo feature #### Proposed Implementation The proposed undo/redo mechanism is facilitated by `VersionedCampusConnect`. It extends `CampusConnect` with an undo/redo history, stored internally as an `history` and `future`. Additionally, it implements the following operations: -* `VersionedCampusConnect#saveCurrentData()` — Saves the current address book state in its future. -* `VersionedCampusConnect#saveOldData()` — Saves the current address book state in its history. -* `VersionedCampusConnect#extractOldData()` — Restores the previous address book state from its history. -* `VersionedCampusConnect#extractUndoneData()` — Restores a previously undone address book state from its history. +* `VersionedCampusConnect#saveCurrentData()` — Saves the current CampusConnect state in its future. +* `VersionedCampusConnect#saveOldData()` — Saves the current CampusConnect state in its history. +* `VersionedCampusConnect#extractOldData()` — Restores the previous CampusConnect state from its history. +* `VersionedCampusConnect#extractUndoneData()` — Restores a previously undone CampusConnect state from its history. These operations are exposed in the `Model` interface as `Model#saveCurrentCampusConnect()`, `Model#undoCampusConnect()` and `Model#redoCampusConnect()` respectively. @@ -188,7 +188,7 @@ Step 1. The user launches the application for the first time. The `VersionedCamp -Step 2. The user executes `delete 5` command to delete the 5th person in the address book. The `delete` command calls `Model#saveCurrentCampusConnect()`, causing the modified state of the CampusConnect after the `delete 5` command executes to be displayed and the old state of CampusConnect to be saved to the history. +Step 2. The user executes `delete 5` command to delete the 5th person in the CampusConnect. The `delete` command calls `Model#saveCurrentCampusConnect()`, causing the modified state of the CampusConnect after the `delete 5` command executes to be displayed and the old state of CampusConnect to be saved to the history. @@ -236,7 +236,7 @@ The `redo` command does the opposite — it calls `Model#redoCampusConnect() -Step 5. The user then decides to execute the command `list`. Commands that do not modify the address book, such as `list`, will usually not call `Model#commitCampusConnect()`, `Model#undoCampusConnect()` or `Model#redoCampusConnect()`. Thus, the `campusConnectStateList` remains unchanged. +Step 5. The user then decides to execute the command `list`. Commands that do not modify the CampusConnect, such as `list`, will usually not call `Model#saveCurrentCampusConnect()`, `Model#undoCampusConnect()` or `Model#redoCampusConnect()`. Thus, the `history` and `future` remain unchanged. @@ -252,7 +252,7 @@ The following activity diagram summarizes what happens when a user executes a ne **Aspect: How undo & redo executes:** -* **Alternative 1 (current choice):** Saves the entire address book. +* **Alternative 1 (current choice):** Saves the entire CampusConnect. * Pros: Easy to implement. * Cons: May have performance issues in terms of memory usage. From 474e87749c007e4b1c5f2e0ee824babe938678d4 Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 08:29:46 +0800 Subject: [PATCH 5/7] Update user stories and use cases --- docs/DeveloperGuide.md | 79 +++++++----------------------------------- 1 file changed, 13 insertions(+), 66 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ef5405bac2d..76d5ac15fba 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -302,19 +302,19 @@ _{Explain here how the data archiving feature will be implemented}_ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -| Priority | As a …​ | I want to …​ | So that I can…​ | -|----------|-------------------------|-----------------------------------------------------------------|-------------------------------------------------------------------------------| -| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | -| `* * *` | user | add a new contact | easily connect with them | -| `* * *` | user | delete a contact | remove entries that I no longer need | -| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | -| `* *` | user | update my contacts information | always keep an updated version of contact information | -| `*` | user with many contacts | search contacts by name | locate a contact easily | -| `*` | user | add a tag information to contacts | easily locate and connect with individuals such as classmates or club members | -| `*` | student | filter contacts by tags such as "group project" or "internship" | easily access related contacts | -| `*` | user | undo my last action | prevent the accidental deletion of all my contacts | - -*{More to be added}* +| Priority | As a …​ | I want to …​ | So that I can…​ | +|----------|-------------------------|-----------------------------------------------------------------|------------------------------------------------------------------------------------| +| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | +| `* * *` | user | add a new contact | easily connect with them | +| `* * *` | user | delete a contact | remove entries that I no longer need | +| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | +| `* *` | user | update my contacts information | always keep an updated version of contact information | +| `* *` | user | undo my last action | prevent the accidental deletion of all my contacts | +| `* *` | user | redo my latest undone action | prevent the accidental undoing of certain actions | +| `*` | user with many contacts | search contacts by name | locate a contact easily | +| `*` | user | add a tag information to contacts | easily locate and connect with individuals such as classmates or club members | +| `*` | student | filter contacts by tags such as "group project" or "internship" | easily access related contacts | +| `*` | user with many tags | categorize tags into different groups | easily organize contacts and locate individuals such as classmates or club members | ### Use cases @@ -428,59 +428,6 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli Use case ends. -**Use case: UC05 - Sort contacts by criterion** - -**MSS** -1. User requests to sort list by criterion. -2. CampusConnect sorts the list. -3. CampusConnect displays the sorted list. - - Use case ends. - -**Extensions** -* 1a. Contact list is empty - - Use case ends. - - -* 1b. Input format is invalid. - * 1b1. CampusConnect shows error message. - * 1b2. User enters input again. - - Steps 1b1-1b2 repeat until input format is valid. - - Use case ends. - - -* 1c. Invalid criterion input. - * 1c1. CampusConnect shows error message. - * 1c2. User enters input again. - - Steps 1c1-1c2 repeat until input format is valid. - - Use case ends. - - -**Use case: UC06 - Pin contacts to the top of the list**\ -**Precondition**: Contact list is not empty - -**MSS** -1. User requests to pin contact to the top of the list. -2. CampusConnect marks contact as pinned. -3. CampusConnect displays success message. - - Use case ends. - -**Extensions** - -* 1a. Input format is invalid. - * 1a1. CampusConnect shows error message. - * 1a2. User enters input again. - - Steps 1a1-1a2 repeat until input format is valid. - - Use case ends. - ### Non-Functional Requirements 1. Should work on any _mainstream OS_ as long as it has Java `17` or above installed. From 9d0794a53bafefbff8fd68db27618108f80dc175 Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 08:38:41 +0800 Subject: [PATCH 6/7] Update activity diagram --- docs/diagrams/CommitActivityDiagram.puml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/diagrams/CommitActivityDiagram.puml b/docs/diagrams/CommitActivityDiagram.puml index b0f1a5bdb41..22c03266cfa 100644 --- a/docs/diagrams/CommitActivityDiagram.puml +++ b/docs/diagrams/CommitActivityDiagram.puml @@ -3,22 +3,23 @@ skin rose skinparam ActivityFontSize 15 skinparam ArrowFontSize 12 start -:User executes command; +:User inputs and +executes command; 'Since the beta syntax does not support placing the condition outside the 'diamond we place it as the true branch instead. - -if () then ([command modifies CampusConnect]) - :Purge undone states in the - "future" stack; - :Save current CampusConnect - to "history" stack; +: Parse command; +if () then ([command will modify CampusConnect]) + :Purge undone states; + :Save current CampusConnect; + :Excutes Command; if () then ([command execution fails]) - : Undo old version of + : Recover to old version of CampusConnect; else ([else]) endif else ([else]) +:Excutes Command; endif stop @enduml From de15d1b3f0a1f91bd6ab88b01ff85414e4766c5d Mon Sep 17 00:00:00 2001 From: CYX22222003 Date: Wed, 6 Nov 2024 09:30:15 +0800 Subject: [PATCH 7/7] Add more use cases --- docs/DeveloperGuide.md | 83 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 76d5ac15fba..e0738e6c87b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -398,13 +398,13 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli Use case ends. -**Use case: UC04 - Add tags to a contact**\ +**Use case: UC04 - Add tags to a contact** **Precondition**: Contact to add tags to already exists **MSS** 1. User requests to add tags to a contact. 2. CampusConnect searches the contact list and finds the correct contact. -3. CampusConnect add tags to the contact. +3. CampusConnect adds tags to the contact. 4. CampusConnect displays success message. Use case ends. @@ -419,14 +419,83 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli Use case ends. -* 1b. Tag already exists for the contact - * 1b1. CampusConnect shows error message. - * 1b2. User enters input again - - Steps 1b1-1b2 repeat until non-duplicate tags are input +* 3a. Tag already exists for the contact + * 3a1. CampusConnect shows error message. Use case ends. +**Use cases: UC05 - Delete a tag from a contact** +**Precondition**: Contact to delete a tag from already exists + +**MSS** +1. User requests to delete a specific tag from a contact +2. CampusConnect searches the contact list and finds the correct contact. +3. CampusConnect deletes the specific tag from the contact +4. CampusConnect displays success message + + Use case ends + +**Extensions** +* 1a. Input format is invalid + * 1a1. CampusConnect shows error message. + * 1a2 User enters input again. + + Steps 1a1-1a2 repeat until input format is valid. + + Use case ends. + +* 3a. The contact does not contain the tag user wants to delete + * 3a1. CampusConnect shows error message. + + Use case ends. + +**Use cases: UC06 - Undo an execution of command** +**Precondition**: At least one valid command has been executed by the user. + +**MSS** +1. User requests to undo the most recent command execution. +2. CampusConnect reverts the most recent command, restoring the data to its previous state +before the command was executed. + + Use case ends + +**Extensions** +* 1a. Input format is invalid. + * 1a1. CampusConnect shows error message. + * 1a2. User enters input again. + + Steps 1a1-1a2 repeat until input format is valid. + + Use case ends. + +* 1b. No earlier data to revert. + * 1b1. CampusConnect shows error message. + + Use cases ends. + +**Use Case: UC07 - Redo Command Execution** + +**Precondition: The user has previously undone at least one command.** + +**MSS:** +1. The user requests to redo the most recently undone command. +2. CampusConnect restores the data to the state it was in immediately before the undo. + + Use case ends. + +**Extensions:** +* 1a. Invalid Input Format: + * 1a1. CampusConnect displays an error message indicating the input format is invalid. + * 1a2. The user re-enters the input. + + Steps 1a1-1a2 repeat until the input format is valid. + + Use case ends. + +* 1b. No More Commands to Redo: + * 1b1. CampusConnect displays an error message indicating that there are no more commands to redo. + + Use case ends. ### Non-Functional Requirements