diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9f3c29b4900..b21d2ab179d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -309,6 +309,68 @@ _{more aspects and alternatives to be added}_ _{Explain here how the data archiving feature will be implemented}_ +### Multiple Teacher’s Address Books (TABs) +**Feature Summary** +- Users are able to create multiple TABs (currently limited to 5). + - Through `new` command +- Users are able to swap between the TABs + - Through `swap` command + +**Implementation** + +Current implementation consists of two parts. First part is creating new books, second part is swapping between books. + +**Creating new Books** + +This feature builds on `MainWindow` class to facilitate communication between the UI and backend functions. It +communicates with `Logic` to create new TABs and uses `Model` class to alter the current `UserPref` instance. + +**Swapping between Books** + +This feature, similar to creating new TABs builds on `MainWindow` class and communicates with `Logic` class to swap +between TABs. It uses `Model` class to fetch the next TAB from `UserPref`. The TABs' information are stored as an +array under `preferences.json` as well as the current TAB's index. `UserPref` loops around the array when it reaches +the end. `Logic` then make use of the path information to call `storage` to update the current TAB. + +**Example** +Given below is an example usage scenario and how the creation of new TAB mechanism behaves at each step. + +Step 1: User enters the `new` command into the Command-Line Interface (CLI) or user navigates via `Files -> New Book` to +create a new TAB. + +The following sequence diagram shows how creation of new book work: +![Creating New Book](images/CreateNewBookSequenceDiagram.png) + +Step 1.1: User adds X amount of TABs (up to 5): + +![Swapping Books](images/CreatingNewBookState0.png) + +![Swapping Books](images/CreatingNewBookState1.png) + +Step 2: User enters the `swap` command or navigates via `Files -> New Book` to toggle between TABs: + +![Swapping Books](images/SwapState0.png) + +The following sequence diagram shows how swapping works: +NOTE: Sequence Diagram Only includes added portions +![Swapping Books](images/SwapBooksSequenceDiagram.png) + +**Design Considerations** + +- Alternative 1 (current choice): Toggle between books + - Pros: + - Swapping between TAB occurs within 1 window + - Open for future features + - Cons: + - Might be more prone to bugs due to complex implementations + - Might be slower to load between books +- Alternative 2: Multiple copies of .java applications + - Pros + - Easier to implement + - Can have multiple books open at once + - Cons: + - User need to create multiple books + - Less open to future feature extensions (communicate between books) -------------------------------------------------------------------------------------------------------------------- diff --git a/docs/diagrams/CreateNewBookSequenceDiagram.puml b/docs/diagrams/CreateNewBookSequenceDiagram.puml new file mode 100644 index 00000000000..cd7b4138832 --- /dev/null +++ b/docs/diagrams/CreateNewBookSequenceDiagram.puml @@ -0,0 +1,54 @@ +@startuml +'https://plantuml.com/sequence-diagram +!include style.puml +box UiPart UI_COLOR_T1 +participant ":MainWindow" as MainWindow UI_COLOR +end box + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":ModelManager" as ModelManager MODEL_COLOR +end box + +box ReadOnlyUserPrefs PREF_COLOR +participant ":UserPrefs" as UserPrefs PREF_COLOR_T1 +end box +[-> MainWindow : handleNewBook() +activate MainWindow + +MainWindow -> LogicManager : addAddressBook() +activate LogicManager + +LogicManager -> ModelManager : addAddressBook() +activate ModelManager + +ModelManager -> UserPrefs : addAddressBook() +activate UserPrefs + +UserPrefs --> ModelManager +deactivate UserPrefs + +ModelManager --> LogicManager +deactivate ModelManager + +LogicManager -> ModelManager : getAllAddressBookFilePath() +activate ModelManager + +ModelManager -> UserPrefs : getAllAddressBookFilePath() +activate UserPrefs + +UserPrefs --> ModelManager +deactivate UserPrefs + +ModelManager --> LogicManager +deactivate ModelManager + +LogicManager --> MainWindow : result +deactivate LogicManager + +[<--MainWindow +deactivate LogicManager +@enduml diff --git a/docs/diagrams/CreatingNewBookState0.puml b/docs/diagrams/CreatingNewBookState0.puml new file mode 100644 index 00000000000..2493be3c1e2 --- /dev/null +++ b/docs/diagrams/CreatingNewBookState0.puml @@ -0,0 +1,21 @@ +@startuml +!include style.puml +skinparam ClassFontColor #000000 +skinparam ClassBorderColor #000000 + +title Initial state + +package States <> { + class State1 as "addressBook.json" + class State2 as "addressBook1.json" + class State3 as "addressBook2.json" +} + +State1 -[hidden]right-> State2 +State2 -[hidden]right-> State3 +hide State2 +hide State3 + +class Pointer as "Currently Loaded Book" #FFFFFF +Pointer -up-> State1 +@end diff --git a/docs/diagrams/CreatingNewBookState1.puml b/docs/diagrams/CreatingNewBookState1.puml new file mode 100644 index 00000000000..acc44321d75 --- /dev/null +++ b/docs/diagrams/CreatingNewBookState1.puml @@ -0,0 +1,22 @@ +@startuml +!include style.puml +skinparam ClassFontColor #000000 +skinparam ClassBorderColor #000000 + +title After command "new" or clicking "New Book" button + +package States <> { + class State1 as "addressBook.json" + class State2 as "addressBook1.json" + class State3 as "addressBook2.json" +} + +State1 -[hidden]right-> State2 +State2 -[hidden]right-> State3 + +hide State3 + +class Pointer as "Currently Loaded Book" #FFFFFF + +Pointer -up-> State1 +@end diff --git a/docs/diagrams/SwapBooksSequenceDiagram.puml b/docs/diagrams/SwapBooksSequenceDiagram.puml new file mode 100644 index 00000000000..09a9ba4cd76 --- /dev/null +++ b/docs/diagrams/SwapBooksSequenceDiagram.puml @@ -0,0 +1,84 @@ +@startuml +'https://plantuml.com/sequence-diagram +!include style.puml +box UiPart UI_COLOR_T1 +participant ":MainWindow" as MainWindow UI_COLOR +end box + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +end box + + + +box Model MODEL_COLOR_T1 +participant ":ModelManager" as ModelManager MODEL_COLOR +end box + +box Storage STORAGE_COLOR_T1 +participant ":Storage" as Storage STORAGE_COLOR +end box + +box ReadOnlyUserPrefs PREF_COLOR +participant ":UserPrefs" as UserPrefs PREF_COLOR_T1 +end box + +[-> MainWindow : handleSwap() +activate MainWindow + +MainWindow -> LogicManager : swapAddressBook() +activate LogicManager + + + +LogicManager -> ModelManager : getNextAddressBookPath() +activate ModelManager + +ModelManager -> UserPrefs : getNextAddressBookPath() +activate UserPrefs + +UserPrefs -> UserPrefs : incrementIndex() +activate UserPrefs + +UserPrefs --> UserPrefs +deactivate UserPrefs + +UserPrefs -> UserPrefs : setAddressBookFilePath(Path) +activate UserPrefs + +UserPrefs --> UserPrefs +deactivate UserPrefs + +UserPrefs --> ModelManager : result +deactivate UserPrefs + +ModelManager --> LogicManager +deactivate ModelManager + + + +LogicManager -> Storage : readAddressBook(Path) +activate Storage + +Storage --> LogicManager +deactivate Storage + +LogicManager -> Storage : setAddressBook(AddressBookStorage) +activate Storage + +Storage --> LogicManager +deactivate Storage + + +LogicManager -> ModelManager : setAddressBook(ReadOnlyAddressBook) +activate ModelManager + +ModelManager --> LogicManager +deactivate ModelManager + +LogicManager --> MainWindow +deactivate LogicManager + +[<--MainWindow +deactivate LogicManager +@enduml diff --git a/docs/diagrams/SwapState0.puml b/docs/diagrams/SwapState0.puml new file mode 100644 index 00000000000..1b0961bfb28 --- /dev/null +++ b/docs/diagrams/SwapState0.puml @@ -0,0 +1,22 @@ +@startuml +!include style.puml +skinparam ClassFontColor #000000 +skinparam ClassBorderColor #000000 + +title After command "swap" or clicking "Swap Book" button + +package States <> { + class State1 as "addressBook.json" + class State2 as "addressBook1.json" + class State3 as "addressBook2.json" +} + +State1 -[hidden]right-> State2 +State2 -[hidden]right-> State3 + +hide State3 + +class Pointer as "Currently Loaded Book" #FFFFFF + +Pointer -up-> State2 +@end diff --git a/docs/diagrams/UndoRedoState0.puml b/docs/diagrams/UndoRedoState0.puml index 96e30744d24..34885420931 100644 --- a/docs/diagrams/UndoRedoState0.puml +++ b/docs/diagrams/UndoRedoState0.puml @@ -15,6 +15,6 @@ State2 -[hidden]right-> State3 hide State2 hide State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State1 @end diff --git a/docs/diagrams/UndoRedoState1.puml b/docs/diagrams/UndoRedoState1.puml index 01fcb9b2b96..0e2c8c72d33 100644 --- a/docs/diagrams/UndoRedoState1.puml +++ b/docs/diagrams/UndoRedoState1.puml @@ -16,7 +16,7 @@ State2 -[hidden]right-> State3 hide State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState2.puml b/docs/diagrams/UndoRedoState2.puml index bccc230a5d1..0ce7073e187 100644 --- a/docs/diagrams/UndoRedoState2.puml +++ b/docs/diagrams/UndoRedoState2.puml @@ -14,7 +14,7 @@ package States <> { State1 -[hidden]right-> State2 State2 -[hidden]right-> State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State3 @end diff --git a/docs/diagrams/UndoRedoState3.puml b/docs/diagrams/UndoRedoState3.puml index ea29c9483e4..50bf43b3f34 100644 --- a/docs/diagrams/UndoRedoState3.puml +++ b/docs/diagrams/UndoRedoState3.puml @@ -14,7 +14,7 @@ package States <> { State1 -[hidden]right-> State2 State2 -[hidden]right-> State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState4.puml b/docs/diagrams/UndoRedoState4.puml index 1b784cece80..83cbe4c740c 100644 --- a/docs/diagrams/UndoRedoState4.puml +++ b/docs/diagrams/UndoRedoState4.puml @@ -14,7 +14,7 @@ package States <> { State1 -[hidden]right-> State2 State2 -[hidden]right-> State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State2 @end diff --git a/docs/diagrams/UndoRedoState5.puml b/docs/diagrams/UndoRedoState5.puml index 88927be32bc..fc89dd99d2d 100644 --- a/docs/diagrams/UndoRedoState5.puml +++ b/docs/diagrams/UndoRedoState5.puml @@ -14,7 +14,7 @@ package States <> { State1 -[hidden]right-> State2 State2 -[hidden]right-> State3 -class Pointer as "Current State" #FFFFF +class Pointer as "Current State" #FFFFFF Pointer -up-> State3 note right on link: State ab2 deleted. diff --git a/docs/diagrams/style.puml b/docs/diagrams/style.puml index fad8b0adeaa..658edca53d2 100644 --- a/docs/diagrams/style.puml +++ b/docs/diagrams/style.puml @@ -13,6 +13,12 @@ !define UI_COLOR_T3 #166800 !define UI_COLOR_T4 #0E4100 +!define PREF_COLOR #Violet +!define PREF_COLOR_T1 #DarkOrchid +!define PREF_COLOR_T2 #DarkMagenta +!define PREF_COLOR_T3 #DarkSlateBlue +!define PREF_COLOR_T4 #Indigo + !define LOGIC_COLOR #3333C4 !define LOGIC_COLOR_T1 #C8C8FA !define LOGIC_COLOR_T2 #6A6ADC diff --git a/docs/images/CreateNewBookSequenceDiagram.png b/docs/images/CreateNewBookSequenceDiagram.png new file mode 100644 index 00000000000..2885b4ea839 Binary files /dev/null and b/docs/images/CreateNewBookSequenceDiagram.png differ diff --git a/docs/images/CreatingNewBookState0.png b/docs/images/CreatingNewBookState0.png new file mode 100644 index 00000000000..6aacdfec827 Binary files /dev/null and b/docs/images/CreatingNewBookState0.png differ diff --git a/docs/images/CreatingNewBookState1.png b/docs/images/CreatingNewBookState1.png new file mode 100644 index 00000000000..0787173753e Binary files /dev/null and b/docs/images/CreatingNewBookState1.png differ diff --git a/docs/images/SwapBooksSequenceDiagram.png b/docs/images/SwapBooksSequenceDiagram.png new file mode 100644 index 00000000000..5926946bf05 Binary files /dev/null and b/docs/images/SwapBooksSequenceDiagram.png differ diff --git a/docs/images/SwapState0.png b/docs/images/SwapState0.png new file mode 100644 index 00000000000..e5fa39f12b1 Binary files /dev/null and b/docs/images/SwapState0.png differ