diff --git a/README.md b/README.md index 99005012a90..494fc89c998 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ [![CI Status](https://github.com/AY2223S1-CS2103T-W13-1/tp/workflows/Java%20CI/badge.svg)](https://github.com/AY2223S1-CS2103T-W13-1/tp/actions) StudMap (SM) is a desktop app for managing your students, 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, SM can get your -student management tasks done faster than traditional GUI apps. +while still having the benefits of a Graphical User Interface (GUI). If you can type fast, SM can get your student +management tasks done faster than traditional GUI apps. ![Ui](docs/images/Ui.png) - ## Site Map + * [About Us](docs/AboutUs.md) * [User Guide](docs/UserGuide.md) * [Developer Guide](docs/DeveloperGuide.md) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 3e739ba0e20..7fcb1e7b01d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,15 +1,15 @@ --- -layout: page -title: Developer Guide +layout: page title: Developer Guide --- -* Table of Contents -{:toc} + +* Table of Contents {:toc} -------------------------------------------------------------------------------------------------------------------- ## **Acknowledgements** -* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +* {list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the + original source as well} -------------------------------------------------------------------------------------------------------------------- @@ -23,7 +23,10 @@ Refer to the guide [_Setting up and getting started_](SettingUp.md).
-:bulb: **Tip:** The `.puml` files used to create diagrams in this document can be found in the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. Refer to the [_PlantUML Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit diagrams. +:bulb: **Tip:** The `.puml` files used to create diagrams in this document can be found in +the [diagrams](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams/) folder. Refer to the [_PlantUML +Tutorial_ at se-edu/guides](https://se-education.org/guides/tutorials/plantUml.html) to learn how to create and edit +diagrams.
### Architecture @@ -36,7 +39,11 @@ Given below is a quick overview of main components and how they interact with ea **Main components of the architecture** -**`Main`** has two classes called [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). It is responsible for, +**`Main`** has two classes +called [`Main`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/Main.java) +and [`MainApp`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). It +is responsible for, + * At app launch: Initializes the components in the correct sequence, and connects them up with each other. * At shut down: Shuts down the components and invokes cleanup methods where necessary. @@ -49,19 +56,23 @@ The rest of the App consists of four components. * [**`Model`**](#model-component): Holds the data of the App in memory. * [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk. - **How the architecture components interact with each other** -The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete 1`. +The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues +the command `delete 1`. Each of the four main components (also shown in the diagram above), * defines its *API* in an `interface` with the same name as the Component. -* implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding API `interface` mentioned in the previous point. +* implements its functionality using a concrete `{Component Name}Manager` class (which follows the corresponding + API `interface` mentioned in the previous point. -For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the implementation of a component), as illustrated in the (partial) class diagram below. +For example, the `Logic` component defines its API in the `Logic.java` interface and implements its functionality using +the `LogicManager.java` class which follows the `Logic` interface. Other components interact with a given component +through its interface rather than the concrete class (reason: to prevent outside component's being coupled to the +implementation of a component), as illustrated in the (partial) class diagram below. @@ -69,13 +80,20 @@ The sections below give more details of each component. ### UI component -The **API** of this component is specified in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java) +The **API** of this component is specified +in [`Ui.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/Ui.java) ![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` 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) +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) The `UI` component, @@ -86,19 +104,23 @@ The `UI` component, ### Logic component -**API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java) +** +API** : [`Logic.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/logic/Logic.java) Here's a (partial) class diagram of the `Logic` component: How the `Logic` component works: + 1. When `Logic` is called upon to execute a command, it uses the `AddressBookParser` class to parse the user command. -1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `AddCommand`) which is executed by the `LogicManager`. +1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `AddCommand`) which is + executed by the `LogicManager`. 1. The command can communicate with the `Model` when it is executed (e.g. to add a person). 1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`. -The Sequence Diagram below illustrates the interactions within the `Logic` component for the `execute("delete 1")` API call. +The Sequence Diagram below illustrates the interactions within the `Logic` component for the `execute("delete 1")` API +call. ![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png) @@ -110,11 +132,18 @@ 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 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 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. + +* When called upon to parse a user command, the `AddressBookParser` 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 + 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. ### Model component -**API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java) + +** +API** : [`Model.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/model/Model.java) @@ -122,9 +151,13 @@ How the parsing works: 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` 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) +* 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)
:information_source: **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.
@@ -132,17 +165,21 @@ The `Model` component,
- ### Storage component -**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java) +** +API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java) 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 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`) + +* 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 + 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 @@ -158,25 +195,33 @@ This section describes some noteworthy details on how certain features are imple #### 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 following operations: +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 +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. +* `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. -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#commitAddressBook()`, `Model#undoAddressBook()` +and `Model#redoAddressBook()` 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 initial address book state, and the `currentStatePointer` pointing to that single address book state. +Step 1. The user launches the application for the first time. The `VersionedAddressBook` will be initialized with the +initial address book state, and the `currentStatePointer` pointing to that single address book state. ![UndoRedoState0](images/UndoRedoState0.png) -Step 2. The user executes `delete 5` command to delete the 5th person 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 state. +Step 2. The user executes `delete 5` command to delete the 5th person 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 +state. ![UndoRedoState1](images/UndoRedoState1.png) -Step 3. The user executes `add n/David …​` to add a new person. The `add` command also calls `Model#commitAddressBook()`, causing another modified address book state to be saved into the `addressBookStateList`. +Step 3. The user executes `add n/David …​` to add a new person. The `add` command also calls `Model#commitAddressBook()` +, causing another modified address book state to be saved into the `addressBookStateList`. ![UndoRedoState2](images/UndoRedoState2.png) @@ -184,7 +229,9 @@ Step 3. The user executes `add n/David …​` to add a new person. The `add` co -Step 4. The user now decides that adding the person 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` once to the left, pointing it to the previous address book state, and restores the address book to that state. +Step 4. The user now decides that adding the person 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` +once to the left, pointing it to the previous address book state, and restores the address book to that state. ![UndoRedoState3](images/UndoRedoState3.png) @@ -201,17 +248,23 @@ The following sequence diagram shows how the undo operation works: -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#redoAddressBook()`, which shifts the `currentStatePointer` once +to the right, pointing to the previously undone state, and restores the address book to that state.
:information_source: **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()` to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
-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. +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. ![UndoRedoState4](images/UndoRedoState4.png) -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 purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern desktop applications follow. +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 +purged. Reason: It no longer makes sense to redo the `add n/David …​` command. This is the behavior that most modern +desktop applications follow. ![UndoRedoState5](images/UndoRedoState5.png) @@ -224,13 +277,12 @@ 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. - * Pros: Easy to implement. - * Cons: May have performance issues in terms of memory usage. + * Pros: Easy to implement. + * Cons: May have performance issues in terms of memory usage. -* **Alternative 2:** Individual command knows how to undo/redo by - itself. - * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). - * Cons: We must ensure that the implementation of each individual command are correct. +* **Alternative 2:** Individual command knows how to undo/redo by itself. + * Pros: Will use less memory (e.g. for `delete`, just save the person being deleted). + * Cons: We must ensure that the implementation of each individual command are correct. _{more aspects and alternatives to be added}_ @@ -267,7 +319,6 @@ _{Explain here how the data archiving feature will be implemented}_ **Value proposition**: help tutors better keep track of their students’ progress in their assigned module. - ### User stories Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` @@ -283,7 +334,6 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli | `* *` | tutor | filter the students by attribute | locate a student easily | | `* *` | tutor | create new labels to tag my students with | better differentiate the students | - ### Use cases (For all use cases below, the **System** is the `StudMap` and the **Actor** is the `Tutor`, unless specified otherwise) @@ -292,12 +342,12 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli **MSS** -1. Tutor requests to list students -2. StudMap shows a list of students -3. Tutor requests to delete a specific student in the list -4. StudMap deletes the student +1. Tutor requests to list students +2. StudMap shows a list of students +3. Tutor requests to delete a specific student in the list +4. StudMap deletes the student - Use case ends. + Use case ends. **Extensions** @@ -315,33 +365,36 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli **MSS** -1. Tutor requests to add a student -2. StudMap adds the student +1. Tutor requests to add a student +2. StudMap adds the student - Use case ends. + Use case ends. **Extensions** * 1a. The given format for users is invalid * 1a1. StudMap shows an error message. - - Use case ends. + Use case ends. *{More to be added}* ### Non-Functional Requirements 1. The software should work on any _mainstream OS_ as long as it has Java `11` or above installed. -2. The software should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. +2. The software should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical + usage. 3. The software should be able to start up in 30 seconds. -4. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. +4. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be + able to accomplish most of the tasks faster using commands than using the mouse. 5. The software should be able to be used without an installer. 6. The software should not depend on a remote server. 7. If the software crashes or becomes unresponsive, the student records should not be lost. -8. The GUI should work well (i.e., should not cause any resolution-related inconveniences to the user) for standard screen resolutions 1920x1080 and higher and for screen scales 100% and 125%. -9. The GUI should be usable (i.e., all functions can be used even if the user experience is not optimal) for resolutions 1280x720 and higher and for screen scales 150%. +8. The GUI should work well (i.e., should not cause any resolution-related inconveniences to the user) for standard + screen resolutions 1920x1080 and higher and for screen scales 100% and 125%. +9. The GUI should be usable (i.e., all functions can be used even if the user experience is not optimal) for resolutions + 1280x720 and higher and for screen scales 150%. 10. The software should be packaged into a single JAR file. 11. The software should not exceed 100MB in size. 12. The documentation should not exceed 15MB per file. @@ -351,14 +404,16 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli * **Tutor**: Teaching assistant for the specific module * **Student**: A person that is partaking in a module. -* **Module**: The university class that the student is enrolled in, encoded by a unique module code consisting of a 2-3 letter prefix that generally denotes the discipline, and 4 digits at the back, the first of which indicates the level of the module. -* **JAR file**: package file format typically used to aggregate many Java class files and associated metadata and resources into one file for distribution. +* **Module**: The university class that the student is enrolled in, encoded by a unique module code consisting of a 2-3 + letter prefix that generally denotes the discipline, and 4 digits at the back, the first of which indicates the level + of the module. +* **JAR file**: package file format typically used to aggregate many Java class files and associated metadata and + resources into one file for distribution. * **GUI**: main interface that the user interacts with to input commands and view results. * **Mainstream OS**: Windows, Linux, Unix, OS-X * **Tag**: A label for students defined by the user, possibly shared by multiple students. * **Attribute**: Characteristics of students that all students have. - -------------------------------------------------------------------------------------------------------------------- ## **Appendix: Instructions for manual testing** @@ -374,15 +429,16 @@ testers are expected to do more *exploratory* testing. 1. Initial launch - 1. Download the jar file and copy into an empty folder + 1. Download the jar file and copy into an empty folder - 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. + 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be + optimum. 1. Saving window preferences - 1. Resize the window to an optimum size. Move the window to a different location. Close the window. + 1. Resize the window to an optimum size. Move the window to a different location. Close the window. - 1. Re-launch the app by double-clicking the jar file.
+ 1. Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained. 1. _{ more test cases …​ }_ @@ -391,16 +447,17 @@ testers are expected to do more *exploratory* testing. 1. Deleting a person while all persons are being shown - 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list. + 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list. - 1. Test case: `delete 1`
- Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. + 1. Test case: `delete 1`
+ Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. + Timestamp in the status bar is updated. - 1. Test case: `delete 0`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. + 1. Test case: `delete 0`
+ Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. - 1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
- Expected: Similar to previous. + 1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)
+ Expected: Similar to previous. 1. _{ more test cases …​ }_ @@ -408,6 +465,6 @@ testers are expected to do more *exploratory* testing. 1. Dealing with missing/corrupted data files - 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_ + 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_ 1. _{ more test cases …​ }_ diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1834187a435..3c5f57c7f25 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,12 +1,12 @@ --- -layout: page -title: User Guide +layout: page title: User Guide --- -StudMap (SM) is a desktop app for managing your students, 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, SM can get your student management tasks done faster than traditional GUI apps. +StudMap (SM) is a desktop app for managing your students, 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, SM can get your student management +tasks done faster than traditional GUI apps. -* Table of Contents -{:toc} +* Table of Contents {:toc} -------------------------------------------------------------------------------------------------------------------- @@ -18,22 +18,25 @@ StudMap (SM) is a desktop app for managing your students, optimized for use via 1. Copy the file to the folder you want to use as the _home folder_ for your StudMap. -1. Double-click the file to start the app. The GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
+1. Double-click the file to start the app. The GUI similar to the below should appear in a few seconds. Note how the app + contains some sample data.
[Sample UI To be added] -1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will open the help window.
+1. Type the command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will + open the help window.
Some example commands you can try: - * **`list`** : Lists all students. + * **`list`** : Lists all students. - * **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a student named `John Doe` to the StudMap. + * **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : Adds a student + named `John Doe` to the StudMap. - * **`delete`**`3` : Deletes the 3rd student shown in the current list. + * **`delete`**`3` : Deletes the 3rd student shown in the current list. - * **`clear`** : Deletes all students. + * **`clear`** : Deletes all students. - * **`exit`** : Exits the app. + * **`exit`** : Exits the app. 1. Refer to the [Features](#features) below for details of each command. @@ -57,10 +60,12 @@ StudMap (SM) is a desktop app for managing your students, optimized for use via * Parameters can be in any order.
e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. -* If a parameter is expected only once in the command but you specified it multiple times, only the last occurrence of the parameter will be taken.
+* If a parameter is expected only once in the command but you specified it multiple times, only the last occurrence of + the parameter will be taken.
e.g. if you specify `p/12341234 p/56785678`, only `p/56785678` will be taken. -* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be ignored.
+* Extraneous parameters for commands that do not take in parameters (such as `help`, `list`, `exit` and `clear`) will be + ignored.
e.g. if the command specifies `help 123`, it will be interpreted as `help`. @@ -74,7 +79,6 @@ Shows a message explaning how to access the help page. Format: `help` - ### Adding a student: `add` Adds a student to the StudMap. @@ -86,6 +90,7 @@ A student can have any number of tags (including 0) Examples: + * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` * `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` @@ -101,16 +106,18 @@ Edits an existing student in the StudMap. Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…​` -* 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, …​ +* 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 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. +* 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 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. + +* `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 students by name: `find` @@ -122,10 +129,11 @@ Format: `find KEYWORD [MORE_KEYWORDS]` * 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` -* Students matching at least one keyword will be returned (i.e. `OR` search). - e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +* 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`
@@ -142,6 +150,7 @@ Format: `delete INDEX` * The index **must be a positive integer** 1, 2, 3, …​ Examples: + * `list` followed by `delete 2` deletes the 2nd student in the StudMap. * `find Betsy` followed by `delete 1` deletes the 1st student in the results of the `find` command. @@ -159,29 +168,36 @@ Format: `exit` ### Saving the data -StudMap data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually. +StudMap data are saved in the hard disk automatically after any command that changes the data. There is no need to save +manually. ### Editing the data file -StudMap data are saved as a JSON file `[JAR file location]/data/studmap.json`. Advanced users are welcome to update data directly by editing that data file. +StudMap data are saved as a JSON file `[JAR file location]/data/studmap.json`. Advanced users are welcome to update data +directly by editing that data file.
:exclamation: Caution: If your changes to the data file makes its format invalid, StudMap will discard all data and start with an empty data file at the next run.
-### Sorting the students: `sort` +### Sorting the students: `sort` + [Coming soon] ### Filtering the students: `filter` + [Coming soon] ### Mark student as present: `mark` + [Coming soon] ### Unmark attendance of a student: `unmark` + [Coming soon] ### Add tag to a student: `addtag` + [Coming soon] @@ -190,7 +206,8 @@ If your changes to the data file makes its format invalid, StudMap will discard ## FAQ **Q**: How do I transfer my data to another Computer?
-**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous StudMap home folder. +**A**: Install the app in the other computer and overwrite the empty data file it creates with the file that contains +the data of your previous StudMap home folder. -------------------------------------------------------------------------------------------------------------------- @@ -198,10 +215,12 @@ If your changes to the data file makes its format invalid, StudMap will discard Action | Format, Examples --------|------------------ -**Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
e.g., `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` +** +Add** | `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
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`
e.g., `delete 3` -**Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`
e.g.,`edit 2 n/James Lee e/jameslee@example.com` +** +Edit** | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]…​`
e.g.,`edit 2 n/James Lee e/jameslee@example.com` **Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake` **List** | `list` **Help** | `help` diff --git a/src/main/java/seedu/address/logic/commands/FilterCommand.java b/src/main/java/seedu/address/logic/commands/FilterCommand.java new file mode 100644 index 00000000000..daa0bf2de67 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/FilterCommand.java @@ -0,0 +1,35 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; + +import seedu.address.commons.core.Messages; +import seedu.address.model.Model; +import seedu.address.model.person.NameContainsKeywordsPredicate; + +/** + * Filters and list all persons in the address book + */ +public class FilterCommand extends Command { + + public static final String COMMAND_WORD = "filter"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Filters all persons whose names contain any of " + + "the specified alphabets (case-insensitive) and displays them as a list with index numbers.\n" + + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + + "Example: " + COMMAND_WORD + " alex"; + + private final NameContainsKeywordsPredicate predicate; + + public FilterCommand(NameContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredPersonList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size())); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 51f2c3fc12a..e3516b6ee3e 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -13,6 +13,7 @@ import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.EditCommand; import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FilterCommand; import seedu.address.logic.commands.FindCommand; import seedu.address.logic.commands.HelpCommand; import seedu.address.logic.commands.ListCommand; @@ -63,15 +64,18 @@ public Command parseCommand(String userInput) throws ParseException { case ListCommand.COMMAND_WORD: return new ListCommand(); - case AddTagCommand.COMMAND_WORD: - return new AddTagCommandParser().parse(arguments); - case ExitCommand.COMMAND_WORD: return new ExitCommand(); + case AddTagCommand.COMMAND_WORD: + return new AddTagCommandParser().parse(arguments); + case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case FilterCommand.COMMAND_WORD: + return new FilterCommandParser().parse(arguments); + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/logic/parser/FilterCommandParser.java b/src/main/java/seedu/address/logic/parser/FilterCommandParser.java new file mode 100644 index 00000000000..005c90f2ea5 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/FilterCommandParser.java @@ -0,0 +1,36 @@ +package seedu.address.logic.parser; + +import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; + +import seedu.address.logic.commands.FilterCommand; +import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.person.NameContainsKeywordsPredicate; + + +/** + * Parses input arguments and create a new FilterCommand object + */ +public class FilterCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the FilterCommand + * and returns a FilterCommand object for execution. + * + * @throws ParseException if the user input does not conform the expected format + */ + @Override + public FilterCommand parse(String args) throws ParseException { + String trimmedArgs = args.trim(); + if (trimmedArgs.isEmpty()) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + } + + String[] nameKeywords = trimmedArgs.split("\\s+"); + + return new FilterCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + } +} diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index d54df471c1f..23a370de719 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -84,4 +84,6 @@ public interface Model { * @throws NullPointerException if {@code predicate} is null. */ void updateFilteredPersonList(Predicate predicate); + + }