Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into update-contact
Browse files Browse the repository at this point in the history
  • Loading branch information
angsongyee committed Mar 20, 2024
2 parents aec3f15 + ecc5fa2 commit c0ebc40
Show file tree
Hide file tree
Showing 35 changed files with 725 additions and 231 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/telegram-alerts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Telegram Pull Request Notifier

on:
pull_request:
types: [opened, review_requested]

jobs:
notification:
runs-on: ubuntu-latest

steps:
# Send a telegram message on pr open or review request
- name: Pull Request Telegram
uses: F2had/[email protected]
with:
bot_token: '${{ secrets.BOTTOKEN }}'
chat_id: '${{ secrets.CHATID }}'
101 changes: 62 additions & 39 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main
<puml src="diagrams/UiClassDiagram.puml" alt="Structure of the UI Component"/>

The UI consists of a `MainWindow` that is made up of parts
e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`,
e.g.`CommandBox`, `ResultDisplay`, `ContactListPanel`, `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.

Expand All @@ -98,7 +98,7 @@ The `UI` component,
* executes user commands using the `Logic` component.
* listens for changes to `Model` data so that the UI can be updated with the modified data.
* keeps a reference to the `Logic` component, because the `UI` relies on the `Logic` to execute commands.
* depends on some classes in the `Model` component, as it displays `Person` object residing in the `Model`.
* depends on some classes in the `Model` component, as it displays `Contact` object residing in the `Model`.

### Logic component

Expand All @@ -122,7 +122,7 @@ PlantUML, the lifeline continues till the end of diagram.

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 creates
1. When `Logic` is called upon to execute a command, it is passed to an `CodeConnectParser` object which in turn creates
a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which
is executed by the `LogicManager`.
Expand All @@ -137,9 +137,9 @@ Here are the other classes in `Logic` (omitted from the class diagram above) tha

How the parsing works:

* When called upon to parse a user command, the `AddressBookParser` class creates an `XYZCommandParser` (`XYZ` is a
* When called upon to parse a user command, the `CodeConnectParser` class creates an `XYZCommandParser` (`XYZ` is a
placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse
the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `AddressBookParser` returns back as
the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `CodeConnectParser` returns back as
a `Command` object.
* All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser`
interface so that they can be treated similarly where possible e.g, during testing.
Expand All @@ -154,9 +154,9 @@ in [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/m

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<Person>` that can be 'observed' e.g. the UI can be bound to
* stores the address book data i.e., all `Contact` objects (which are contained in a `UniqueContactList` object).
* stores the currently 'selected' `Contact` objects (e.g., results of a search query) as a separate _filtered_ list which
is exposed to outsiders as an unmodifiable `ObservableList<Contact>` 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.
Expand All @@ -165,9 +165,11 @@ The `Model` component,

<box type="info" seamless>

**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.<br>
**Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `CodeConnect`,
which `Contact` references. This allows `CodeConnect

` to only require one `Tag` object per unique tag, instead of
each `Contact` needing their own `Tag` objects.<br>

<puml src="diagrams/BetterModelClassDiagram.puml" width="450" />

Expand All @@ -184,14 +186,14 @@ The `Storage` component,

* can save both address book data and user preference data in JSON format, and read them back into corresponding
objects.
* inherits from both `AddressBookStorage` and `UserPrefStorage`, which means it can be treated as either one (if only
* inherits from both `CodeConnectStorage` 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`)

### Common classes

Classes used by multiple components are in the `seedu.addressbook.commons` package.
Classes used by multiple components are in the `seedu.address.commons` package.

--------------------------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -221,55 +223,55 @@ the command is executed:

#### Proposed Implementation

The proposed undo/redo mechanism is facilitated by `VersionedAddressBook`. It extends `AddressBook` with an undo/redo
history, stored internally as an `addressBookStateList` and `currentStatePointer`. Additionally, it implements the
The proposed undo/redo mechanism is facilitated by `VersionedCodeConnect`. It extends `CodeConnect` with an undo/redo
history, stored internally as `codeConnectStateList` and `currentStatePointer`. Additionally, it implements the
following operations:

* `VersionedAddressBook#commit()` — Saves the current address book state in its history.
* `VersionedAddressBook#undo()` — Restores the previous address book state from its history.
* `VersionedAddressBook#redo()` — Restores a previously undone address book state from its history.
* `VersionedCodeConnect#commit()` — Saves the current address book state in its history.
* `VersionedCodeConnect#undo()` — Restores the previous address book state from its history.
* `VersionedCodeConnect#redo()` — Restores a previously undone address book state from its history.

These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()`
and `Model#redoAddressBook()` respectively.
These operations are exposed in the `Model` interface as `Model#commitCodeConnect()`, `Model#undoCodeConnect()`
and `Model#redoCodeConnect()` respectively.

Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.

Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the
Step 1. The user launches the application for the first time. The `VersionedCodeConnect` will be initialized with the
initial address book state, and the `currentStatePointer` pointing to that single address book state.

<puml src="diagrams/UndoRedoState0.puml" alt="UndoRedoState0" />

Step 2. The user executes `delete 5` command to delete the 5th contact in the address book. The `delete` command
calls `Model#commitAddressBook()`, causing the modified state of the address book after the `delete 5` command executes
to be saved in the `addressBookStateList`, and the `currentStatePointer` is shifted to the newly inserted address book
calls `Model#commitCodeConnect()`, causing the modified state of the address book after the `delete 5` command executes
to be saved in the `codeConnectStateList`, and the `currentStatePointer` is shifted to the newly inserted address book
state.

<puml src="diagrams/UndoRedoState1.puml" alt="UndoRedoState1" />

Step 3. The user executes `add n/David …​` to add a new contact. The `add` command also
calls `Model#commitAddressBook()`, causing another modified address book state to be saved into
the `addressBookStateList`.
calls `Model#commitCodeConnect()`, causing another modified address book state to be saved into
the `codeConnectStateList`.

<puml src="diagrams/UndoRedoState2.puml" alt="UndoRedoState2" />

<box type="info" seamless>

**Note:** If a command fails its execution, it will not call `Model#commitAddressBook()`, so the address book state will
not be saved into the `addressBookStateList`.
**Note:** If a command fails its execution, it will not call `Model#commitCodeConnect()`, so the address book state will
not be saved into the `codeConnectStateList`.

</box>

Step 4. The user now decides that adding the contact was a mistake, and decides to undo that action by executing
the `undo` command. The `undo` command will call `Model#undoAddressBook()`, which will shift the `currentStatePointer`
the `undo` command. The `undo` command will call `Model#undoCodeConnect()`, which will shift the `currentStatePointer`
once to the left, pointing it to the previous address book state, and restores the address book to that state.

<puml src="diagrams/UndoRedoState3.puml" alt="UndoRedoState3" />


<box type="info" seamless>

**Note:** If the `currentStatePointer` is at index 0, pointing to the initial AddressBook state, then there are no
previous AddressBook states to restore. The `undo` command uses `Model#canUndoAddressBook()` to check if this is the
**Note:** If the `currentStatePointer` is at index 0, pointing to the initial CodeConnect state, then there are no
previous CodeConnect states to restore. The `undo` command uses `Model#canUndoCodeConnect()` to check if this is the
case. If so, it will return an error to the user rather
than attempting to perform the undo.

Expand All @@ -290,24 +292,24 @@ Similarly, how an undo operation goes through the `Model` component is shown bel

<puml src="diagrams/UndoSequenceDiagram-Model.puml" alt="UndoSequenceDiagram-Model" />

The `redo` command does the opposite — it calls `Model#redoAddressBook()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state.
The `redo` command does the opposite — it calls `Model#redoCodeConnect()`, which shifts the `currentStatePointer` once to the right, pointing to the previously undone state, and restores the address book to that state.

<box type="info" seamless>

**Note:** If the `currentStatePointer` is at index `addressBookStateList.size() - 1`, pointing to the latest address
book state, then there are no undone AddressBook states to restore. The `redo` command uses `Model#canRedoAddressBook()`
**Note:** If the `currentStatePointer` is at index `codeConnectStateList.size() - 1`, pointing to the latest address
book state, then there are no undone CodeConnect states to restore. The `redo` command uses `Model#canRedoCodeConnect()`
to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.

</box>

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#commitAddressBook()`, `Model#undoAddressBook()` or `Model#redoAddressBook()`.
Thus, the `addressBookStateList` remains unchanged.
as `list`, will usually not call `Model#commitCodeConnect()`, `Model#undoCodeConnect()` or `Model#redoCodeConnect()`.
Thus, the `codeConnectStateList` remains unchanged.

<puml src="diagrams/UndoRedoState4.puml" alt="UndoRedoState4" />

Step 6. The user executes `clear`, which calls `Model#commitAddressBook()`. Since the `currentStatePointer` is not
pointing at the end of the `addressBookStateList`, all address book states after the `currentStatePointer` will be
Step 6. The user executes `clear`, which calls `Model#commitCodeConnect()`. Since the `currentStatePointer` is not
pointing at the end of the `codeConnectStateList`, all address book states after the `currentStatePointer` will be
purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern
desktop applications follow.

Expand Down Expand Up @@ -400,7 +402,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

### Use cases

(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise)
(For all use cases below, the **System** is the `CodeConnect` and the **Actor** is the `user`, unless specified otherwise)

**Use case: UC01 - Delete a contact**

Expand Down Expand Up @@ -508,7 +510,27 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
* 1b1. CodeConnect shows an empty list.
Use case ends.

**Use case: UC07 - Sending an email to a specific contact**
**Use case: UC07 - Search a contact by tech stack**

**MSS**

1. User requests to look up contacts with specific tech stack.
2. CodeConnect checks each contact’s tech stack in the list.
3. CodeConnect shows a list of contacts that match the criteria.

Use case ends.

**Extensions**

* 1a. No tech stack is given.
* 1a1. CodeConnect shows an error message.
Use case ends.

* 1b. There are no contacts in the list that match the criteria.
* 1b1. CodeConnect shows an empty list.
Use case ends.

**Use case: UC08 - Sending an email to a specific contact**

**MSS**

Expand All @@ -523,6 +545,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli

* 1a. The default desktop mail application is not available on the system.
* 1a1. CodeConnect displays an error message indicating that the desktop mail application is not supported.

Use case ends.

*{More to be added}*
Expand Down
2 changes: 1 addition & 1 deletion docs/SettingUp.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ If you plan to use Intellij IDEA (highly recommended):

1. **Learn the design**

When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [AddressBook’s architecture](DeveloperGuide.md#architecture).
When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [CodeConnect’s architecture](DeveloperGuide.md#architecture).

1. **Do the tutorials**
These tutorials will help you get acquainted with the codebase.
Expand Down
Loading

0 comments on commit c0ebc40

Please sign in to comment.