diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4fc1837229..6eabb846c6 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -197,16 +197,23 @@ The next sequence diagram shows the loading of user data into `Terminus`. ![](attachments/MainInit.png) -The next sequence diagram shows an instance of command execution. +The next sequence diagram shows an instance the main logic loop. ![](attachments/MainLogic.png) > 📝 **Note:** The cross on each lifeline represents the end of objects lifeline. > Due to the limitation of PlantUML the line continues to extend. +The next sequence diagram shows an instance of command execution. +![](attachments/loopLogic.png) + +
+ The next sequence diagram show the termination of `Terminus` ![](attachments/MainExit.png) - + +
+ ### 3.2 UI Component ![](attachments/UIClassDiagram.png) @@ -221,6 +228,7 @@ The `Ui` implements the following functionality: - Getting of user input through `getUserInput()` and `requestCommand()`. - Printing string arrays to the output through `printSection()`. +
### 3.3 Parser Component ![](attachments/ParserClassDiagram.png) @@ -235,6 +243,7 @@ The `CommandParser` implements the following functionality: - Keeps track of the workspace. - Provides functionality to list all commands for the help `Command`. +
### 3.4 Command Component ![](attachments/CommandClassDiagram.png) @@ -250,6 +259,7 @@ The `CommandResult` will contains certain attributes that will indicate certain - Indicate the if file operations are required and the corresponding actions. - Tracks if the program should terminate. +
### 3.5 Module Component @@ -265,6 +275,9 @@ The `ModuleManager` implements the below functionality: - List all module names. - Grants access to the different types of content stored by `NusModule`. + +
+ ### 3.6 Content Component ![](attachments/Content.png) @@ -279,6 +292,9 @@ which inherit from the abstract `Content` class. The `ContentManager` allows a g - Listing all contents. - Accessing the arraylist of contents. + +
+ ### 3.7 Active Recall Component ![Active Recall Class Diagram](attachments/ActiveRecallClassDiagram.png) @@ -299,6 +315,9 @@ after the user has provided feedback on the difficulty of the question. It uses For further details on the implementation, head to [4.2 Active Recall Implementation](#42-active-recall-implementation). + +
+ ### 3.8 Storage Component @@ -317,6 +336,8 @@ The `StorageManager` component: data easily with any available text editor. +
+ ## 4. Implementation This section introduces the specific implementation details and design consideration of some features in TermiNUS. @@ -383,6 +404,7 @@ This section shows the design considerations that were taken into account when i Moreover, implementing a timetable for each module might be slightly redundant as a view schedule command could offer a similar functionality albeit not sorted out. +
### 4.2 Active Recall Implementation @@ -476,7 +498,7 @@ tweak the curve parameters if needed. The parameters of the logistic curve can be viewed here: [https://www.desmos.com/calculator/qefovvnuhx](https://www.desmos.com/calculator/qefovvnuhx). - +
### 4.3 Workspace Implementation @@ -598,6 +620,7 @@ Eventually the team decide to go with the second implementation, as we require m workspaces and would like to create our own workspace for each feature. Aside from that the `Command` provides common functionality that many commands need hence reducing repetition of code. +
### 4.4 Conflict Manager Implementation @@ -649,6 +672,8 @@ We hope that all users are aware of the conflicts as soon as possible, so that c Although it is slightly challenging to identify conflicts when not adding a new schedule, we think that the timetable feature can help in identifying conflicts manually. +
+ ### 4.5 Storage Implementation To view the high-level diagram, head to [3.8 Storage](#38-storage-component). @@ -696,10 +721,14 @@ of file I/O operations using `NIO2` to be in its own class which is in the `Stor of the storage type class to inherit the functionality of the `Storage` class while adding their own checks and third party imports on top of it. +
+ #### 4.5.2 Loading Storage Implementation This section details the technical information of `StorageManager` when `Terminus` loads data in the `data` directory. + + ##### 4.5.2.1 Current Implementation ![](attachments/StorageLoadSequenceDiagram_part1.png) @@ -760,10 +789,14 @@ create the specified folder. Due to this, it may abort loading of any notes for ModuleManager. Secondly, this method is meant to load existing data and not to create any data that is not the main `data` directory or the `main.json` file. +
+ #### 4.5.3 Execute CommandResult with Storage Implementation This section details the technical information of `StorageManager` when `Terminus` performs required file I/O operations stated in `CommandResult` after an execution of a `Command`. + + ##### 4.5.3.1 Current Implementation ![](attachments/StorageCommandResultSequenceDiagram.png) @@ -791,6 +824,9 @@ requirements from the execution of a `Command`. **Chosen Solution:** Separate file I/O operation by the type of file involved first which is the solution of StorageType first. This means that each Storage type have a higher decoupling from one another. + +
+ ### 4.6 Adding Content Implementation This section details the technical information of adding a `Content` into `ContentManager`. @@ -814,6 +850,8 @@ store in its arraylist of `Note`. **Step 4** Upon, the successful execution of adding the new `Note` into `ContentManager`, it will return a `CommandResult` with its respective message for user `Ui` response purposes. + + #### 4.6.2 Design Consideration **Aspect: Checks arguments in ContentManager or the AddCommand.** @@ -826,6 +864,8 @@ its respective message for user `Ui` response purposes. **Chosen Solution:** To validate arguments in the AddCommand instead. This is due to the generic type of `ContentManager` that may lead to nested conditions if the arguments are checked within the `ContentManager`. +
+ ### 4.7 Deleting Content Implementation This section details the technical information of deleting a `Content` from `ContentManager`. @@ -855,6 +895,8 @@ for user `Ui` response purposes. **Chosen Solution:** To avoid the mixing up of content number and array index, we decided to pass the content number into `ContentManager` where it will subtract the given number by 1 to get the index number for the arraylist. +
+ ## 5. Documentation, Logging, Testing and DevOps This section details how we document, log, test and perform development operations. @@ -961,7 +1003,7 @@ You may monitor your Codecov progress in your pull request if you successfully p 1. To exit **TermiNUS**, enter the `exit` command. -
+ ### D.2: Workspace Navigation @@ -983,7 +1025,8 @@ You may monitor your Codecov progress in your pull request if you successfully p > 💡 Advanced users can navigate to sub-workspaces using a single command. E.g. `go cs2113T schedule` -
+ + ### D.3: Timetable Feature @@ -1001,7 +1044,7 @@ You may monitor your Codecov progress in your pull request if you successfully p b. `timetable 1` (1 is not a valid day) -
+ ### D.4: Module Workspace @@ -1028,7 +1071,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `update 0 "cs2101"` (Invalid module index to be updated) -
+ ### D.5: Accessing a Specific Module @@ -1045,7 +1088,7 @@ You may monitor your Codecov progress in your pull request if you successfully p b. `go X` (Where X is not an existing user module) -
+ ### D.6: Accessing the Question Workspace @@ -1063,7 +1106,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `question` from the main workspace (Question workspace can not be accessed from the main workspace) -
+ ### D.7: Add Question @@ -1081,7 +1124,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `add` (A pair of question and answer must be present for an add command) -
+ ### D.8: View Questions @@ -1102,7 +1145,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `view` from the main workspace (To view questions, execute `view` from the question workspace) -
+ ### D.9: Delete Question @@ -1120,7 +1163,8 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `delete` (The delete command has to be followed by a valid index) -
+ + ### D.10: Test Feature @@ -1134,7 +1178,7 @@ You may monitor your Codecov progress in your pull request if you successfully p a. `test` from the main workspace (The test feature can only be accessed from the question workspace) -
+ ### D.11: Accessing the Note Workspace @@ -1152,7 +1196,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `note` from the main workspace (Note workspace can not be accessed from the main workspace) -
+ ### D.12: Add Note @@ -1170,7 +1214,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `add` (A pair of note title and content must be present for an add command) -
+ ### D.13: View Notes @@ -1191,7 +1235,6 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `view` from the main workspace (To view notes, execute `view` from the note workspace) -
### D.14: Delete Note @@ -1209,7 +1252,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `delete` (The delete command has to be followed by a valid index) -
+ ### D.15: Export Notes @@ -1225,7 +1268,7 @@ You may monitor your Codecov progress in your pull request if you successfully p b. `export` from the main workspace (The export command must be executed in the note workspace) -
+ ### D.16: Accessing the Schedule Workspace @@ -1243,7 +1286,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `schedule` from the main workspace (Schedule workspace can not be accessed from the main workspace) -
+ ### D.17: Add Schedule @@ -1261,7 +1304,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `add` (All arguments must be present for a valid add command) -
+ ### D.18: View Schedules @@ -1282,7 +1325,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `view` from the main workspace (To view schedules, execute `view` from the schedule workspace) -
+ ### D.19: Delete Schedule @@ -1300,7 +1343,7 @@ You may monitor your Codecov progress in your pull request if you successfully p c. `delete` (The delete command has to be followed by a valid index) -
+ ### D.20: Help Feature @@ -1314,7 +1357,7 @@ You may monitor your Codecov progress in your pull request if you successfully p a. `help X` (Where X is any trailing number or word) -
+ ### D.21: Navigate to Previous Workspace @@ -1330,4 +1373,4 @@ You may monitor your Codecov progress in your pull request if you successfully p b. `back` from the main workspace (The back command cannot be used in the main workspace) -
+ diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a4e6471515..85a4eb4ac3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -82,6 +82,8 @@ Terminologies used throughout this guide: --- +
+ ## Getting Started This section will detail the `TermiNUS` installation guide, as well a quick guide on how to use @@ -160,6 +162,8 @@ The below table represents what each means. |`duration`|The `duration` must be a **positive** integer and upon addition with `start_time`, it must not exceed the 24-hour limit of the day. For example, if `start_time` is `21:00`, `2` is a valid `duration` but `-1` and `4` are not.| |`valid_file_name`|Any value that has the tag `valid file name` cannot be empty, cannot have more than **30** characters and can only contains [ASCII](https://www.asciitable.com/) characters **between the dec value of 32 and 126 inclusive** with the **exception** of `/`, `\n`, `\r`, `\t`, `\0`, `\f`, `'`, `?`, `*`, `\ `, `<`, `>`, `"`, `:`, `.` , | | +
+ ## Section: Managing all your modules All commands related to the workspace `Module Management` will be displayed in this section. These @@ -284,6 +288,8 @@ Updated CS2113T to CS2113 successfully. --- +
+ ## Returning to previous workspace **Format:** `back` @@ -364,6 +370,8 @@ List of Module workspace commands: --- +
+ ## Section: Note All commands related to the workspace `Note` will be displayed in this section. These commands @@ -444,6 +452,8 @@ workspace. Example 1: `view` +
+ Expected Output 1: ``` @@ -539,6 +549,8 @@ Exporting notes... Check the data folder. --- +
+ ## Section: Schedule All commands related to the workspace `Schedule` will be displayed in this section. These commands @@ -616,6 +628,8 @@ Views a list of schedules in the module when in the schedule workspace. Example 1: `view` +
+ Expected Output 1: ``` @@ -657,6 +671,8 @@ Your link on 'CS2113T Tutorial 1' has been deleted! --- +
+ ## Section: Question All commands related to the workspace Question will be displayed in this section. These commands @@ -676,6 +692,8 @@ List of Question workspace commands: |back|escape and return to the module workspace| |exit|exit and closes TermiNUS| +
+ ### Accessing question workspace **Format:** `question` @@ -771,6 +789,8 @@ Your question on 'What is 1+1?' has been deleted! [CS2113T > question] >>> ``` +
+ ### Testing Yourself with Active Recall **Format:** `test {question_count}` @@ -852,6 +872,8 @@ Returning you back to main program. --- +
+ ## Displaying all schedules across all modules **Format:** `timetable {day}` @@ -933,6 +955,8 @@ Format: timetable {day} [] >>> ``` +
+ ## Advanced Usage of Commands **Format:** ` ` @@ -976,6 +1000,8 @@ Your question on 'What is Java?' has been added! ___ +
+ ## FAQ **Q:** Can I edit the information in the`data` directory? **A:** Yes! **TermiNUS** saves and loads your information from the `data` folder. You are able to edit the files @@ -1005,6 +1031,8 @@ solve the issue. Secondly, if you are running macOS or Linux, we do not delete f ___ +
+ ## Workspace Command Summary | Action | Format| Examples | diff --git a/docs/attachments/ActiveRecallSequenceDiagram.png b/docs/attachments/ActiveRecallSequenceDiagram.png index 4fa5b572b7..8015334eb8 100644 Binary files a/docs/attachments/ActiveRecallSequenceDiagram.png and b/docs/attachments/ActiveRecallSequenceDiagram.png differ diff --git a/docs/attachments/ConflictManagerSequenceDiagram.png b/docs/attachments/ConflictManagerSequenceDiagram.png index 6afbd3dbab..234d35cd01 100644 Binary files a/docs/attachments/ConflictManagerSequenceDiagram.png and b/docs/attachments/ConflictManagerSequenceDiagram.png differ diff --git a/docs/attachments/MainLogic.png b/docs/attachments/MainLogic.png index 947d74c385..abf561c546 100644 Binary files a/docs/attachments/MainLogic.png and b/docs/attachments/MainLogic.png differ diff --git a/docs/attachments/TimetableGetDailySchedule.png b/docs/attachments/TimetableGetDailySchedule.png index 6313a30fa0..f372300747 100644 Binary files a/docs/attachments/TimetableGetDailySchedule.png and b/docs/attachments/TimetableGetDailySchedule.png differ diff --git a/docs/attachments/TimetableSequenceDiagram.png b/docs/attachments/TimetableSequenceDiagram.png index 6aee4f0f9b..46ffd0824a 100644 Binary files a/docs/attachments/TimetableSequenceDiagram.png and b/docs/attachments/TimetableSequenceDiagram.png differ diff --git a/docs/attachments/loopLogic.png b/docs/attachments/loopLogic.png new file mode 100644 index 0000000000..55a6cf90c2 Binary files /dev/null and b/docs/attachments/loopLogic.png differ diff --git a/docs/uml/ActiveRecallSequenceDiagram.puml b/docs/uml/ActiveRecallSequenceDiagram.puml index 696f71012a..df81d06705 100644 --- a/docs/uml/ActiveRecallSequenceDiagram.puml +++ b/docs/uml/ActiveRecallSequenceDiagram.puml @@ -37,7 +37,7 @@ activate GameEnvironment destroy QuestionGenerator return -return CommandResult(true) +return CommandResult destroy GameEnvironment @enduml \ No newline at end of file diff --git a/docs/uml/ConflictManagerSequenceDiagram.puml b/docs/uml/ConflictManagerSequenceDiagram.puml index 5c8507e5ed..cca8747eab 100644 --- a/docs/uml/ConflictManagerSequenceDiagram.puml +++ b/docs/uml/ConflictManagerSequenceDiagram.puml @@ -9,6 +9,7 @@ endbox box Content CONTENT_BOX_COLOR participant ":ConflictManager" as ConflictManager CONTENT_COLOR participant ":ContentManager" as ContentManager CONTENT_COLOR +participant ":Link" as Link CONTENT_COLOR endbox box Module MODULE_BOX_COLOR @@ -16,49 +17,36 @@ participant ":ModuleManager" as ModuleManager MODULE_COLOR participant ":NusModule" as NusModule MODULE_COLOR endbox +autoactivate on -Activate AddLinkCommand +activate AddLinkCommand create ConflictManager -AddLinkCommand -> ConflictManager: ConflictManager() -Activate ConflictManager +AddLinkCommand -> ConflictManager: ConflictManager(moduleManager, newLink) +return +AddLinkCommand -> ConflictManager: getConflictingSchedule() + ConflictManager -> ConflictManager: getAllLinks() + ConflictManager -> ModuleManager: getAllModules() + return modules -ConflictManager -> ConflictManager: getConflictingSchedule() -Activate ConflictManager + loop For each NusModule in modules -ConflictManager -> ConflictManager: getAllLinks() -Activate ConflictManager + ConflictManager -> ModuleManager: getModule(NusModule) + return NusModule -ConflictManager -> ModuleManager: getAllModules() -Activate ModuleManager -NusModule --> ModuleManager: modules -Activate NusModule - -loop For each NusModule in modules - ModuleManager -> NusModule: getModule(NusModule) - Deactivate ModuleManager - NusModule -> ContentManager : getContentManager() - Activate ContentManager - Deactivate NusModule - ContentManager -> ContentManager: getContents() - Activate ContentManager - ContentManager --> ContentManager: contents - Deactivate ContentManager - ContentManager --> ConflictManager: addAll(contents) - Deactivate ContentManager - ConflictManager --> ConflictManager: AllLinks - Deactivate ConflictManager + ConflictManager-> NusModule : getContentManager() + return ContentManager + ConflictManager -> ContentManager: getContents() + return Links + end + return Links loop For each Link in AllLinks opt same day && overlapping start-time to end-time - ConflictManager -> ConflictManager: append(LinkDescription) - ConflictManager --> ConflictManager: conflictingSchedule - Deactivate ConflictManager + ConflictManager -> Link :getViewDescription() + return description + end end -end - - -end -ConflictManager --> AddLinkCommand: conflictingSchedule +return conflictingSchedule destroy ConflictManager @enduml \ No newline at end of file diff --git a/docs/uml/MainLogic.puml b/docs/uml/MainLogic.puml index 3617904d80..b966562f11 100644 --- a/docs/uml/MainLogic.puml +++ b/docs/uml/MainLogic.puml @@ -19,46 +19,13 @@ participant ":StorageManager" as StorageManager STORAGE_COLOR endbox autoactivate on --> Terminus: run() +-> Terminus: start() Terminus -> Terminus: initialize() ref over Terminus,CommandParser: Initialization return Terminus -> Terminus : runCommandsUntilExit() loop True - Terminus -> Ui : requestCommand () - return String - Terminus -> Terminus: handleUserInput(input) - Terminus -> CommandParser: parseCommand(input) - return Command - Terminus -> Command : execute(moduleManager) - create CommandResult - Command -> CommandResult - return CommandResult - return CommandResult - return CommandResult - break commandResult.isExit() == true - note over Terminus, CommandResult : Breaks out of loop and Returns runCommandsUntilExit() - end - Terminus -> Terminus: handleCommandResult(commandResult) - alt commandResult.getNewCommandParser() != null - Terminus -> CommandResult: getNewCommandParser() - return CommandParser - Terminus -> Ui:printParserBanner(parser, moduleManager) - return - else else - Terminus -> Ui:printSection(commandResult.getMessage()) - return - end - return - Terminus -> Terminus: handleStorage(commandResult) - opt commandResult.hasChange() == true - Terminus -> StorageManager: executeCommandResult(moduleManager, commandResult) - return - end - Terminus -> StorageManager: updateMainJsonFile(moduleManager) - return - return - destroy CommandResult + ref over Terminus, StorageManager: Loop Logic end return Terminus -> Terminus :exit() diff --git a/docs/uml/TimetableGetDailySchedule.puml b/docs/uml/TimetableGetDailySchedule.puml index 706e27eefe..415104a4bb 100644 --- a/docs/uml/TimetableGetDailySchedule.puml +++ b/docs/uml/TimetableGetDailySchedule.puml @@ -5,62 +5,37 @@ mainframe sd getDailySchedule -box Command COMMAND_BOX_COLOR -participant ":TimetableCommand" as TimetableCommand COMMAND_COLOR +box Content CONTENT_BOX_COLOR +participant ":Timetable" as Timetable CONTENT_COLOR +participant ":Link" as Link CONTENT_COLOR endbox -participant ":Timetable" as Timetable - box Module MODULE_BOX_COLOR participant ":ModuleManager" as ModuleManager MODULE_COLOR participant ":NusModule" as NusModule MODULE_COLOR endbox -box Content CONTENT_BOX_COLOR -participant ":ContentManager" as ContentManager CONTENT_COLOR -participant ":Link" as Link CONTENT_COLOR -endbox - -TimetableCommand -> Timetable: getDailySchedule() -Activate Timetable +autoactivate on + -> Timetable: getDailySchedule() Timetable -> ModuleManager: getAllModules() -Activate ModuleManager -NusModule --> ModuleManager: modules -Activate NusModule +return modules loop For each NusModule in modules - ModuleManager -> NusModule: getModule(NusModule) - - Deactivate ModuleManager - - NusModule -> ContentManager : getContentManager() - - Activate ContentManager - Deactivate NusModule - - loop For each Link in ContentManager - - ContentManager -> Link: getContents() - Activate Link - Deactivate ContentManager - - Link->Link: getDay() - Activate Link #DarkSalmon - Link --> Link: currentDay - - opt if currentDay equals to user argument Day - Deactivate Link - - Link -> Link: getViewDescription() - Activate Link #DarkSalmon - - Link --> Link: description - Deactivate Link - Link -> Link: append(description) - Activate Link + Timetable -> ModuleManager: getModule(NusModule) + return NusModule + Timetable -> NusModule : getContentManager() + return ContentManager + Timetable -> Timetable: listDailySchedule(contentManager, today) + return Links +end +loop For each schedule in dailySchedule + Timetable -> Link: getViewDescription() + return description +end + +return schedule - end @enduml \ No newline at end of file diff --git a/docs/uml/TimetableSequenceDiagram.puml b/docs/uml/TimetableSequenceDiagram.puml index c5e8a7bd90..8014d37d07 100644 --- a/docs/uml/TimetableSequenceDiagram.puml +++ b/docs/uml/TimetableSequenceDiagram.puml @@ -5,7 +5,6 @@ box Command COMMAND_BOX_COLOR participant ":TimetableCommand" as TimetableCommand COMMAND_COLOR endbox -participant ":Timetable" as Timetable box Module MODULE_BOX_COLOR @@ -14,6 +13,7 @@ participant ":NusModule" as NusModule MODULE_COLOR endbox box Content CONTENT_BOX_COLOR +participant ":Timetable" as Timetable CONTENT_COLOR participant ":ContentManager" as ContentManager CONTENT_COLOR participant ":Link" as Link CONTENT_COLOR endbox @@ -39,7 +39,7 @@ Timetable --> TimetableCommand: weeklyScehdule Deactivate Timetable -else +else else ref over TimetableCommand, Timetable, ModuleManager, NusModule, ContentManager getDailySchedule end diff --git a/docs/uml/loopLogic.puml b/docs/uml/loopLogic.puml new file mode 100644 index 0000000000..d0e1c082f1 --- /dev/null +++ b/docs/uml/loopLogic.puml @@ -0,0 +1,58 @@ +@startuml +'https://plantuml.com/sequence-diagram +!include SequenceStyle.puml + +box "Main" TERMINUS_BOX_COLOR +participant ":Terminus" as Terminus TERMINUS_COLOR +endbox +box "UI" UI_BOX_COLOR +participant ":Ui" as Ui +endbox +box "Parser" PARSER_BOX_COLOR +participant ":CommandParser" as CommandParser PARSER_COLOR +endbox +box "Command" COMMAND_BOX_COLOR +participant ":Command" as Command COMMAND_COLOR +participant ":CommandResult" as CommandResult COMMAND_COLOR +endbox +box "Storage" STORAGE_BOX_COLOR +participant ":StorageManager" as StorageManager STORAGE_COLOR +endbox +autoactivate on +mainframe sd Loop Logic +activate Terminus +Terminus -> Ui : requestCommand () +return String +Terminus -> Terminus: handleUserInput(input) + Terminus -> CommandParser: parseCommand(input) + return Command + Terminus -> Command : execute(moduleManager) + create CommandResult + Command -> CommandResult + return CommandResult +return CommandResult +return CommandResult +break commandResult.isExit() == true + note over Terminus, CommandResult : Breaks out of loop and Returns runCommandsUntilExit() +end +Terminus -> Terminus: handleCommandResult(commandResult) + alt commandResult.getNewCommandParser() != null + Terminus -> CommandResult: getNewCommandParser() + return CommandParser + Terminus -> Ui:printParserBanner(parser, moduleManager) + return + else else + Terminus -> Ui:printSection(commandResult.getMessage()) + return + end +return +Terminus -> Terminus: handleStorage(commandResult) + opt commandResult.hasChange() == true + Terminus -> StorageManager: executeCommandResult(moduleManager, commandResult) + return + end + Terminus -> StorageManager: updateMainJsonFile(moduleManager) + return +return +destroy CommandResult +@enduml \ No newline at end of file