Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
# Conflicts:
#	docs/images/BetterModelClassDiagram.png
#	docs/images/ModelClassDiagram.png
  • Loading branch information
zoebelle-pang committed Apr 3, 2024
2 parents 6a8b71f + 48d74e5 commit d0a82cc
Show file tree
Hide file tree
Showing 59 changed files with 983 additions and 199 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ dependencies {
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'

implementation 'org.apache.commons:commons-lang3:3.12.0'

implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.0'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.7.4'

Expand Down
58 changes: 57 additions & 1 deletion docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The **API** of this component is specified in [`Ui.java`](https://github.com/se-

![Structure of the UI Component](images/UiClassDiagram.png)

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 consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter` `HelpWindow` `ViewWindow` 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)

Expand Down Expand Up @@ -155,6 +155,62 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa

This section describes some noteworthy details on how certain features are implemented.

### Filter Command

#### Implementation

The Address book filter is made with `GradeSubjectFilterPredicate`. It extends from `Predicate` functional interface and is used to set as a condition to check that for each student, the `Grade` and `Subject` specified is met. Predicates created can be updated using the method `Model#updateFilteredPersonList(predicate)`.

The `Grade` and `Subject` classes are set as additional data fields in `Person`.

* Both classes have exposed methods `isEmpty()`, to check if the grade and subject parameters are specified.
* When unspecified:
* `Grade()` equals to `Grade("-")` (i.e. "-" will be shown when there is no grade for the student.)
* `Subject()` equals to `Subject("No subject")` (i.e. "No subject" will be shown when no subject is assigned for the student.)

Given below is an example usage scenario and what the predicate is at each step.

Step 1. The user launches the application for the first time. The student's contacts in a form of `FilteredList` will be shown, where the predicate states that condition is true for all.

<div markdown="span" class="alert alert-info">:information_source: **Note:** By default, `FilteredList` predicate is set to `FilteredList.ALWAYS_TRUE`. But since both are equivalent, `Model.PREDICATE_SHOW_ALL_PERSONS` is used.

</div>

![FilterState0](images/FilterState0-FilteredList.png)

Step 2. The user executes `filter g/A` command to get all students in the `FilteredList` who has an "A" grade. The `filter` command creates `GradeSubjectFilterPredicate`, and calls `Model#updateFilteredPersonList(predicate)`, updating the list to show students that has an "A" grade.

![FilterState1](images/FilterState1-FilteredList.png)

Calling `list` command will revert the predicate back to `Model.PREDICATE_SHOW_ALL_PERSONS`.

<br>

The following sequence diagram shows how a filter operation goes through the `Logic` component:

![FilterSequenceDiagram-Logic](images/FilterSequenceDiagram-Logic.png)

<div markdown="span" class="alert alert-info">:information_source: **Note:** The lifeline for `FilterCommand` and `GradeSubjectFilterPredicate` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

</div>

Similarly, how a filter operation goes through the `Model` component is shown below:

![FilterSequenceDiagram-Model](images/FilterSequenceDiagram-Model.png)

The following activity diagram summarizes what happens when a tutor executes a filter command.

![FilterActivityDiagram](images/FilterActivityDiagram.png)

#### Design considerations

* Alternative 1: Filtered address book result can be saved, since in practice, there will only be a few combinations of filters.
* Pros: Operation will be fast as the number of students increases.
* Cons: More memory usage.
* Alternative 2: Introduce command history to avoid typing long commands.
* Pros: Useful for the entire application, and would use less memory (e.g. storing the first 10 commands).
* Cons: Harder to implement.

### \[Proposed\] Undo/redo feature

#### Proposed Implementation
Expand Down
88 changes: 52 additions & 36 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ layout: page
title: User Guide
---

TutorsGo is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.
TutorsGo is a **desktop app for managing contacts, optimized for use via a Command Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, TutorsGo can get your contact management tasks done faster than traditional GUI apps.

* Table of Contents
{:toc}
Expand All @@ -14,11 +14,11 @@ TutorsGo is a **desktop app for managing contacts, optimized for use via a Comma

1. Ensure you have Java `11` or above installed in your Computer.

1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases).
1. Download the latest `.jar` from [here](https://github.com/AY2324S2-CS2103-F15-2/tp/releases).

1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook.

1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar addressbook.jar` command to run the application.<br>
1. Open a command terminal, `cd` into the folder you put the jar file in, and use the `java -jar <version_no>.jar` command to run the application.<br>
A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.<br>
![Ui](images/Ui.png)

Expand All @@ -27,7 +27,7 @@ TutorsGo is a **desktop app for managing contacts, optimized for use via a Comma

* `list` : Lists all contacts.

* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a contact named `John Doe` to the Address Book.
* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01 d/2024-02-03 1800 at/present pa/paid` : Adds a contact named `John Doe` to the Address Book.

* `delete 3` : Deletes the 3rd contact shown in the current list.

Expand Down Expand Up @@ -79,69 +79,85 @@ Adds a student to the address book.
Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [g/GRADE] [s/SUBJECT] [d/DATETIME] [t/TAG]…​`

<div markdown="span" class="alert alert-primary">:bulb: **Tip:**
A person can have any number of tags (including 0)
A student can have any number of tags (including 0)
</div>
* Grade should only contain a single letter from A to D, with plus(+), minus(-) or neither.
* Grade follows NUS grading system. (i.e. [A+, A, A-, B+, B, B-, C+, C, D+, D, F, -])
* DateTime should be in yyyy-mm-dd hhmm

Examples:
* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01 g/B+ s/Mathematics d/2024-02-03 1800`
* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal`
* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567`

### Listing all persons : `list`
### Listing all students : `list`

Shows a list of all persons in the address book.
Shows a list of all students in the address book.

Format: `list`

### Editing a person : `edit`
### Editing a student : `edit`

Edits an existing person in the address book.
Edits an existing student in the address book.

Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`

* Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index **must be a positive integer** 1, 2, 3, …​
* Edits the student at the specified `INDEX`. The index refers to the index number shown in the displayed student list. The index **must be a positive integer** 1, 2, 3, …​
* At least one of the optional fields must be provided.
* Existing values will be updated to the input values.
* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative.
* You can remove all the person’s tags by typing `t/` without
* When editing tags, the existing tags of the student will be removed i.e adding of tags is not cumulative.
* You can remove all the student’s tags by typing `t/` without
specifying any tags after it.

Examples:
* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively.
* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags.
* `edit 1 p/91234567 e/johndoe@example.com` Edits the phone number and email address of the 1st student to be `91234567` and `johndoe@example.com` respectively.
* `edit 2 n/Betsy Crower t/` Edits the name of the 2nd student to be `Betsy Crower` and clears all existing tags.

### Locating persons by name: `find`
### Locating students by name: `find`

Finds persons whose names contain any of the given keywords.
Finds students whose names contain any of the given keywords.

Format: `find KEYWORD [MORE_KEYWORDS]`

* The search is case-insensitive. e.g `hans` will match `Hans`
* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans`
* Only the name is searched.
* Only full words will be matched e.g. `Han` will not match `Hans`
* Persons matching at least one keyword will be returned (i.e. `OR` search).
* Students matching at least one keyword will be returned (i.e. `OR` search).
e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang`

Examples:
* `find John` returns `john` and `John Doe`
* `find alex david` returns `Alex Yeoh`, `David Li`<br>
![result for 'find alex david'](images/findAlexDavidResult.png)

### Deleting a person : `delete`
### Filter student by grade / subject: `filter`

Deletes the specified person from the address book.
Filters student who has the specified grade and/or subject.

Format: `filter [g/GRADE] [s/SUBJECT]`

* Search is case-sensitive.
* The order of keywords does not matter.
* At least one of the optional fields must be provided.

### View Schedule: `view`

Displays a calendar to view scheduled classes.

Format: `view`

### Deleting a student : `delete`

Deletes the specified student from the address book.

Format: `delete INDEX`

* Deletes the person at the specified `INDEX`.
* The index refers to the index number shown in the displayed person list.
* Deletes the student at the specified `INDEX`.
* The index refers to the index number shown in the displayed student list.
* The index **must be a positive integer** 1, 2, 3, …​

Examples:
* `list` followed by `delete 2` deletes the 2nd person in the address book.
* `find Betsy` followed by `delete 1` deletes the 1st person in the results of the `find` command.
* `list` followed by `delete 2` deletes the 2nd student in the address book.
* `find Betsy` followed by `delete 1` deletes the 1st student in the results of the `find` command.

### Clearing all entries : `clear`

Expand Down Expand Up @@ -189,14 +205,14 @@ _Details coming soon ..._

## Command summary

Action | Format, Examples
--------|------------------
**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` <br> e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
**Clear** | `clear`
**Delete** | `delete INDEX`<br> e.g., `delete 3`
**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`<br> e.g.,`edit 2 n/James Lee e/jameslee@example.com`
**Find** | `find KEYWORD [MORE_KEYWORDS]`<br> e.g., `find James Jake`
**List** | `list`
**Help** | `help`
**Mark payment**|`mark_payment INDEX` <br> e.g. `mark_payment 2`
**payment_list**|`payment_list`
Action | Format, Examples
--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` <br> e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague`
**Clear** | `clear`
**Delete** | `delete INDEX`<br> e.g., `delete 3`
**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`<br> e.g.,`edit 2 n/James Lee e/jameslee@example.com`
**Find** | `find KEYWORD [MORE_KEYWORDS]`<br> e.g., `find James Jake`
**Filter**| `filter [g/GRADE] [s/SUBJECT]`
**View Schedule**|`view`
**List** | `list`
**Help** | `help`
8 changes: 4 additions & 4 deletions docs/diagrams/BetterModelClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ skinparam arrowThickness 1.1
skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR

AddressBook *-right-> "1" UniquePersonList
AddressBook *-right-> "1" UniquePersonAndDateTimeList
AddressBook *-right-> "1" UniqueTagList
UniqueTagList -[hidden]down- UniquePersonList
UniqueTagList -[hidden]down- UniquePersonList
UniqueTagList -[hidden]down- UniquePersonAndDateTimeList
UniqueTagList -[hidden]down- UniquePersonAndDateTimeList

UniqueTagList -right-> "*" Tag
UniquePersonList -right-> Person
UniquePersonAndDateTimeList -right-> Person

Person -up-> "*" Tag

Expand Down
14 changes: 14 additions & 0 deletions docs/diagrams/FilterActivityDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@startuml
skin rose
skinparam ActivityFontSize 15
skinparam ArrowFontSize 12
start
:User executes filter command;

'Since the beta syntax does not support placing the condition outside the
'diamond we place it as the true branch instead.

:System updates filter predicate;
:Returns filtered student list;
stop
@enduml
55 changes: 55 additions & 0 deletions docs/diagrams/FilterSequenceDiagram-Logic.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
@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 ":FilterCommand" as FilterCommand LOGIC_COLOR
participant ":GradeSubjectFilterPredicate" as GradeSubjectFilterPredicate LOGIC_COLOR
end box

box Model MODEL_COLOR_T1
participant ":Model" as Model MODEL_COLOR
end box
[-> LogicManager : execute(filter g/...)
activate LogicManager

LogicManager -> AddressBookParser : parseCommand()
activate AddressBookParser

create GradeSubjectFilterPredicate
AddressBookParser -> GradeSubjectFilterPredicate
activate GradeSubjectFilterPredicate

GradeSubjectFilterPredicate --> AddressBookParser
deactivate GradeSubjectFilterPredicate

create FilterCommand
AddressBookParser -> FilterCommand
activate FilterCommand

FilterCommand --> AddressBookParser
deactivate FilterCommand

AddressBookParser --> LogicManager
deactivate AddressBookParser

LogicManager -> FilterCommand : execute()
activate FilterCommand

FilterCommand -> Model : updateFilteredPersonList(predicate)
activate Model

Model --> FilterCommand
deactivate Model

FilterCommand --> LogicManager : commandResult
deactivate FilterCommand
FilterCommand -[hidden]-> LogicManager : commandResult
destroy FilterCommand
destroy GradeSubjectFilterPredicate

[<--LogicManager
deactivate LogicManager
@enduml
17 changes: 17 additions & 0 deletions docs/diagrams/FilterSequenceDiagram-Model.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@startuml
!include style.puml
skinparam ArrowFontStyle plain

box Model MODEL_COLOR_T1
participant ":Model" as Model MODEL_COLOR
end box

[-> Model : updateFilteredPersonList(predicate)
activate Model

Model -> Model :setPredicate(predicate)

[<-- Model
deactivate Model

@enduml
18 changes: 18 additions & 0 deletions docs/diagrams/FilterState0.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@startuml
!include style.puml
skinparam ClassFontColor #000000
skinparam ClassBorderColor #000000
skinparam ClassBackgroundColor #FFFFAA

title FilteredList

package Predicates {
class State1 as "<u>Model.PREDICATE_SHOW_ALL_PERSONS</u>"
class State2 as "<u>:GradeSubjectFilterPredicate</u>"
}
State1 -[hidden]right-> State2
hide State2

class Pointer as "Current State" #FFFFFF
Pointer -up-> State1
@end
17 changes: 17 additions & 0 deletions docs/diagrams/FilterState1.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@startuml
!include style.puml
skinparam ClassFontColor #000000
skinparam ClassBorderColor #000000
skinparam ClassBackgroundColor #FFFFAA

title FilteredList

package Predicates {
class State1 as "<u>Model.PREDICATE_SHOW_ALL_PERSONS</u>"
class State2 as "<u>:GradeSubjectFilterPredicate</u>"
}
State1 -[hidden]right-> State2

class Pointer as "Current State" #FFFFFF
Pointer -up-> State2
@end
Loading

0 comments on commit d0a82cc

Please sign in to comment.