diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml new file mode 100644 index 00000000000..fec0c4cbbd1 --- /dev/null +++ b/.github/auto_assign.yml @@ -0,0 +1,37 @@ +# https://probot.github.io/apps/auto-assign/ + + + +# Set to true to add reviewers to PRs +addReviewers: true + +# List of reviewers to add to PRs (GitHub username) +reviewers: + - bwangpj + - Cloud7050 + - mamayuan + - rayshawntan + +# Number of reviewers to randomly add to PRs. +# Set 0 to add all reviewers. +# Defaults to 0 +# numberOfReviewers: 0 + +# Set to true to add assignees to PRs +# addAssignees: true + +# List of assignees to add to PRs (GitHub username). +# Presumably takes priority over reviewers, for usernames set in both +# assignees: +# - assigneeA +# - assigneeB +# - assigneeC + +# Number of assignees to randomly add to PRs. +# Set to 0 to add all assignees. +# Defaults to numberOfReviewers +# numberOfAssignees: 0 + +# Keywords used to decide whether to skip all adding for a PR +skipKeywords: + - no-assign diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..c506a79d4ff --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ +[Enter your description here...] + +[Closes #0.] + +(Please remember to assign the appropriate milestone, via the sidebar at the bottom right. This will allow your PR to be counted by the grading scripts (https://nus-cs2103-ay2324s1.github.io/dashboards/contents/tp-progress.html). Feel free to delete this message when done.) diff --git a/.gitignore b/.gitignore index 284c4ca7cd9..264b5a0ce1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,24 @@ -# Gradle build files -/.gradle/ -/build/ -src/main/resources/docs/ +# macOS Finder files +.DS_Store # IDEA files /.idea/ /out/ /*.iml -# Storage/log files +# VSCode extension build files +/bin/ + +# JVM crash logs +/hs_err_pid[0-9]*.log + +# Gradle build files +/.gradle/ +/build/ +/src/main/resources/docs/ + +# App data/log files /data/ /config.json -/preferences.json +/settings.json /*.log.* -hs_err_pid[0-9]*.log - -# Test sandbox files -src/test/data/sandbox/ - -# MacOS custom attributes files created by Finder -.DS_Store -docs/_site/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..0fb677e1f57 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.detectIndentation": false, + "editor.insertSpaces": true +} diff --git a/README.md b/README.md index 13f5c77403f..f2dfb5857cb 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ -[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) - -![Ui](docs/images/Ui.png) - -* This is **a sample project for Software Engineering (SE) students**.
- Example usages: - * as a starting point of a course project (as opposed to writing everything from scratch) - * as a case study -* The project simulates an ongoing software project for a desktop application (called _AddressBook_) used for managing contact details. - * It is **written in OOP fashion**. It provides a **reasonably well-written** code base **bigger** (around 6 KLoC) than what students usually write in beginner-level SE modules, without being overwhelmingly big. - * It comes with a **reasonable level of user and developer documentation**. -* It is named `AddressBook Level 3` (`AB3` for short) because it was initially created as a part of a series of `AddressBook` projects (`Level 1`, `Level 2`, `Level 3` ...). -* For the detailed documentation of this project, see the **[Address Book Product Website](https://se-education.org/addressbook-level3)**. -* This project is a **part of the se-education.org** initiative. If you would like to contribute code to this project, see [se-education.org](https://se-education.org#https://se-education.org/#contributing) for more info. +# ConText + +[![Java CI](https://github.com/AY2324S1-CS2103-W14-3/tp/actions/workflows/gradle.yml/badge.svg)](https://github.com/AY2324S1-CS2103-W14-3/tp/actions/workflows/gradle.yml) +[![codecov](https://codecov.io/gh/AY2324S1-CS2103-W14-3/tp/graph/badge.svg?token=KT7MNHKALX)](https://codecov.io/gh/AY2324S1-CS2103-W14-3/tp) + +For information as well as detailed user/developer documentation, check out the [product website](https://ay2324s1-cs2103-w14-3.github.io/tp/). + +![UI](./docs/images/Ui.png) + +This project is based on the AddressBook-Level3 project created by the [SE-EDU initiative](https://se-education.org). diff --git a/build.gradle b/build.gradle index a2951cc709e..5a047ecc6fd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,23 +1,76 @@ plugins { - id 'java' - id 'checkstyle' - id 'com.github.johnrengelman.shadow' version '7.1.2' + // application includes java id 'application' + id 'checkstyle' + id 'jacoco' + id 'com.github.johnrengelman.shadow' version '7.1.2' } -mainClassName = 'seedu.address.Main' - -sourceCompatibility = JavaVersion.VERSION_11 -targetCompatibility = JavaVersion.VERSION_11 - repositories { mavenCentral() - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } -checkstyle { - toolVersion = '10.2' +dependencies { + String versionJUnit = '5.10.0' + /* NOTE + * Upgrading Jackson to 2.15.2 causes some tests to fail, as saving Config's + * Path results in a full path instead of the original relative one. + */ + String versionJackson = '2.7.0' + /* NOTE + * We stay on JavaFX 17 instead of 21, for better Java 11 compatibility in + * general. + * + * The documentation states that Java 17 is required for either, but Gluon's + * download page states otherwise: + * • https://openjfx.io/openjfx-docs/ + * • https://gluonhq.com/products/javafx/ + */ + String versionJavaFx = '17.0.9' + + implementation group: 'org.openjfx', name: 'javafx-base', version: versionJavaFx, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-base', version: versionJavaFx, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-base', version: versionJavaFx, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-controls', version: versionJavaFx, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-controls', version: versionJavaFx, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-controls', version: versionJavaFx, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: versionJavaFx, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: versionJavaFx, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: versionJavaFx, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: versionJavaFx, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: versionJavaFx, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: versionJavaFx, classifier: 'linux' + + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: versionJackson + implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: versionJackson + + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: versionJUnit + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: versionJUnit +} + + + +// https://docs.gradle.org/current/userguide/img/javaPluginTasks.png +defaultTasks 'clean', 'test' + +java { + // targetCompatibility also defaults to sourceCompatibility + sourceCompatibility JavaVersion.VERSION_11 +} + +application { + mainClass = 'swe.context.Main' +} + +clean { + delete './data/' + delete './settings.json' + delete fileTree('./') { include '*.log.*' } +} + +run { + enableAssertions true } test { @@ -26,6 +79,11 @@ test { } task coverage(type: JacocoReport) { + // "Task ':coverage' uses this output of task ':test' without declaring an + // explicit or implicit dependency. This can lead to incorrect results being + // produced, depending on what order the tasks are executed." + dependsOn test + sourceDirectories.from files(sourceSets.main.allSource.srcDirs) classDirectories.from files(sourceSets.main.output) executionData.from files(jacocoTestReport.executionData) @@ -40,33 +98,10 @@ task coverage(type: JacocoReport) { } } -dependencies { - String jUnitVersion = '5.4.0' - String javaFxVersion = '17.0.7' - - implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win' - implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac' - implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux' - implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win' - implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac' - implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux' - implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win' - implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac' - implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux' - implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' - implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' - implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' - - 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' - - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: jUnitVersion - - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: jUnitVersion +checkstyle { + toolVersion = '10.2' } shadowJar { - archiveFileName = 'addressbook.jar' + archiveFileName = 'context.jar' } - -defaultTasks 'clean', 'test' diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index eb761a9b9a7..44048c50540 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -1,434 +1,425 @@ - - - - + "https://checkstyle.org/dtds/configuration_1_3.dtd" +> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + + + - - - + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + - - - - - - - - - - - - - + - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + - - - - + - - - - - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + - - - - + + - - - - - + + + - + - - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - + + - - + + - - + + - - + + - - + + - - + + + + - - + + + + + + + + + - - - - + - - - - - - - - - + + + + + + - + + - - - - - - - - - - diff --git a/copyright.txt b/copyright.txt deleted file mode 100644 index 93aa2a39ce2..00000000000 --- a/copyright.txt +++ /dev/null @@ -1,9 +0,0 @@ -Some code adapted from http://code.makery.ch/library/javafx-8-tutorial/ by Marco Jakob - -Copyright by Susumu Yoshida - http://www.mcdodesign.com/ -- address_book_32.png -- AddressApp.ico - -Copyright by Jan Jan Kovařík - http://glyphicons.com/ -- calendar.png -- edit.png diff --git a/deliverables/[CS2103-W14-3][ConText].jar b/deliverables/[CS2103-W14-3][ConText].jar new file mode 100644 index 00000000000..1ad63f36b42 Binary files /dev/null and b/deliverables/[CS2103-W14-3][ConText].jar differ diff --git a/deliverables/[CS2103-W14-3][ConText]DG.pdf b/deliverables/[CS2103-W14-3][ConText]DG.pdf new file mode 100644 index 00000000000..6b4ba4a4663 Binary files /dev/null and b/deliverables/[CS2103-W14-3][ConText]DG.pdf differ diff --git a/deliverables/[CS2103-W14-3][ConText]UG.pdf b/deliverables/[CS2103-W14-3][ConText]UG.pdf new file mode 100644 index 00000000000..d01510b3713 Binary files /dev/null and b/deliverables/[CS2103-W14-3][ConText]UG.pdf differ diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 1c9514e966a..f5a9d0f1afe 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,57 +3,50 @@ layout: page title: About Us --- -We are a team based in the [School of Computing, National University of Singapore](http://www.comp.nus.edu.sg). +We are a team taking CS2103 at NUS in AY23/24 S1. -You can reach us at the email `seer[at]comp.nus.edu.sg` +This page is designed to closely follow the format required by grading scripts. ## Project team -### John Doe +### Cloud7050 - +*The public name and image are placeholders.* -[[homepage](http://www.comp.nus.edu.sg/~damithch)] -[[github](https://github.com/johndoe)] -[[portfolio](team/johndoe.md)] + -* Role: Project Advisor +[[github](https://github.com/Cloud7050)] +[[portfolio](./team/cloud7050.md)] -### Jane Doe +- Role: Team Lead +- Responsibilities: Code quality. Assists with: Integration (e.g. maintaining repo, merging PRs), scheduling & tracking (e.g. defining/assigning/editing issues/PRs) - +### mamayuan -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] + -* Role: Team Lead -* Responsibilities: UI - -### Johnny Doe - - - -[[github](http://github.com/johndoe)] [[portfolio](team/johndoe.md)] +[[github](http://github.com/mamayuan)] +[[portfolio](./team/mamayuan.md)] * Role: Developer -* Responsibilities: Data +* Responsibilities: Testing and Integration (e.g. maintaining repo, merging PRs) -### Jean Doe +### bwangpj - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](http://github.com/bwangpj)] +[[portfolio](./team/bwangpj.md)] -* Role: Developer -* Responsibilities: Dev Ops + Threading +- Role: Developer +- Responsibilities: Documentation -### James Doe +### rayshawntan - + -[[github](http://github.com/johndoe)] -[[portfolio](team/johndoe.md)] +[[github](http://github.com/rayshawntan)] +[[portfolio](./team/rayshawntan.md)] -* Role: Developer -* Responsibilities: UI +- Role: Developer +- Responsibilities: Scheduling and tracking diff --git a/docs/Configuration.md b/docs/Configuration.md deleted file mode 100644 index 13cf0faea16..00000000000 --- a/docs/Configuration.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: page -title: Configuration guide ---- - -Certain properties of the application can be controlled (e.g user preferences file location, logging level) through the configuration file (default: `config.json`). diff --git a/docs/DevOps.md b/docs/DevOps.md deleted file mode 100644 index d2fd91a6001..00000000000 --- a/docs/DevOps.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -layout: page -title: DevOps guide ---- - -* Table of Contents -{:toc} - --------------------------------------------------------------------------------------------------------------------- - -## Build automation - -This project uses Gradle for **build automation and dependency management**. **You are recommended to read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html)**. - - -Given below are how to use Gradle for some important project tasks. - - -* **`clean`**: Deletes the files created during the previous build tasks (e.g. files in the `build` folder).
- e.g. `./gradlew clean` - -* **`shadowJar`**: Uses the ShadowJar plugin to creat a fat JAR file in the `build/lib` folder, *if the current file is outdated*.
- e.g. `./gradlew shadowJar`. - -* **`run`**: Builds and runs the application.
- **`runShadow`**: Builds the application as a fat JAR, and then runs it. - -* **`checkstyleMain`**: Runs the code style check for the main code base.
- **`checkstyleTest`**: Runs the code style check for the test code base. - -* **`test`**: Runs all tests. - * `./gradlew test` — Runs all tests - * `./gradlew clean test` — Cleans the project and runs tests - --------------------------------------------------------------------------------------------------------------------- - -## Continuous integration (CI) - -This project uses GitHub Actions for CI. The project comes with the necessary GitHub Actions configurations files (in the `.github/workflows` folder). No further setting up required. - -### Code coverage - -As part of CI, this project uses Codecov to generate coverage reports. When CI runs, it will generate code coverage data (based on the tests run by CI) and upload that data to the CodeCov website, which in turn can provide you more info about the coverage of your tests. - -However, because Codecov is known to run into intermittent problems (e.g., report upload fails) due to issues on the Codecov service side, the CI is configured to pass even if the Codecov task failed. Therefore, developers are advised to check the code coverage levels periodically and take corrective actions if the coverage level falls below desired levels. - -To enable Codecov for forks of this project, follow the steps given in [this se-edu guide](https://se-education.org/guides/tutorials/codecov.html). - -### Repository-wide checks - -In addition to running Gradle checks, CI includes some repository-wide checks. Unlike the Gradle checks which only cover files used in the build process, these repository-wide checks cover all files in the repository. They check for repository rules which are hard to enforce on development machines such as line ending requirements. - -These checks are implemented as POSIX shell scripts, and thus can only be run on POSIX-compliant operating systems such as macOS and Linux. To run all checks locally on these operating systems, execute the following in the repository root directory: - -`./config/travis/run-checks.sh` - -Any warnings or errors will be printed out to the console. - -**If adding new checks:** - -* Checks are implemented as executable `check-*` scripts within the `.github` directory. The `run-checks.sh` script will automatically pick up and run files named as such. That is, you can add more such files if you need and the CI will do the rest. - -* Check scripts should print out errors in the format `SEVERITY:FILENAME:LINE: MESSAGE` - * SEVERITY is either ERROR or WARN. - * FILENAME is the path to the file relative to the current directory. - * LINE is the line of the file where the error occurred and MESSAGE is the message explaining the error. - -* Check scripts must exit with a non-zero exit code if any errors occur. - --------------------------------------------------------------------------------------------------------------------- - -## Making a release - -Here are the steps to create a new release. - -1. Update the version number in [`MainApp.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/MainApp.java). -1. Generate a fat JAR file using Gradle (i.e., `gradlew shadowJar`). -1. Tag the repo with the version number. e.g. `v0.1` -1. [Create a new release using GitHub](https://help.github.com/articles/creating-releases/). Upload the JAR file you created. diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8a861859bfd..f5994d6f149 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -2,49 +2,37 @@ layout: page title: Developer Guide --- -* 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} --------------------------------------------------------------------------------------------------------------------- - -## **Setting up, getting started** - -Refer to the guide [_Setting up and getting started_](SettingUp.md). +- Table of Contents +{:toc} --------------------------------------------------------------------------------------------------------------------- +--- -## **Design** +## Design
- -:bulb: **Tip:** The `.puml` files used to create diagrams in this document `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 are in the `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 -The ***Architecture Diagram*** given above explains the high-level design of the App. +The ***Architecture Diagram*** given above explains the high-level design of the app. Given below is a quick overview of main components and how they interact with each other. **Main components of the architecture** -**`Main`** (consisting of classes [`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)) is in charge of the app launch and shut down. +**`Main`** (consisting of classes [`Main`](https://github.com/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/Main.java) and [`MainApp`](https://github.com/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/MainApp.java)) is in charge of the app launch and shut down. * At app launch, it initializes the other components in the correct sequence, and connects them up with each other. * At shut down, it shuts down the other components and invokes cleanup methods where necessary. The bulk of the app's work is done by the following four components: -* [**`UI`**](#ui-component): The UI of the App. +* [**`UI`**](#ui-component): The UI of the app. * [**`Logic`**](#logic-component): The command executor. -* [**`Model`**](#model-component): Holds the data of the App in memory. +* [**`Model`**](#model-component): Holds the data of the app in memory. * [**`Storage`**](#storage-component): Reads data from, and writes data to, the hard disk. [**`Commons`**](#common-classes) represents a collection of classes used by multiple other components. @@ -68,41 +56,42 @@ 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/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/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. +(Remark: The overlapping triangles into `UiPart` are all class inheritance triangles (limitation of PlantUML).) + +The UI consists of a `MainWindow` that is made up of parts 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. -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/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/resources/view/MainWindow.fxml) 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`. + +The `CommandBox` part keeps a reference to a `CommandBoxHistory` object, which stores the history of entered commands, allowing for the functionality of navigating to previous commands using the up/down arrow keys within the `CommandBox`. ### 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/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/logic/Logic.java) Here's a (partial) class diagram of the `Logic` component: -The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example. +The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1 3 5")` API call as an example. -![Interactions Inside the Logic Component for the `delete 1` Command](images/DeleteSequenceDiagram.png) - -
:information_source: **Note:** The lifeline for `DeleteCommandParser` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. -
+![Interactions Inside the Logic Component for the `delete 1 3 5` Command](images/DeleteSequenceDiagram.png) 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 a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command. +1. When `Logic` is called upon to execute a command, it is passed to an `InputParser` 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`. -1. The command can communicate with the `Model` when it is executed (e.g. to delete a person). +1. The command can communicate with the `Model` when it is executed (e.g. to delete a contact). 1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`. Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command: @@ -110,268 +99,491 @@ 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. +* When called upon to parse a user command, the `InputParser` 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 `InputParser` 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/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/model/Model.java) + 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. +* stores the contacts 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` 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 `Settings` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlySettings` 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.
- - - -
- - ### 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/AY2324S1-CS2103-W14-3/tp/tree/master/src/main/java/swe/context/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). +* can save both contacts data and user preference data in JSON format, and read them back into corresponding objects. +* inherits from both `ContactsStorage` and `SettingsStorage`, 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 `swe.context.commons` package. --------------------------------------------------------------------------------------------------------------------- +--- -## **Implementation** +## Implementation This section describes some noteworthy details on how certain features are implemented. -### \[Proposed\] Undo/redo feature +### Add feature -#### Proposed Implementation +The add feature is facilitated by `ModelManager` and implements `Model`. -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 following sequence diagram shows how the add command works: -* `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. +![AddSequenceDiagram](images/AddSequenceDiagram.png) -These operations are exposed in the `Model` interface as `Model#commitAddressBook()`, `Model#undoAddressBook()` and `Model#redoAddressBook()` respectively. +It adds an contact by calling `Model#addContact`, which adds the newly created contact into the `UniqueContactList`. -Given below is an example usage scenario and how the undo/redo mechanism behaves at each step. +The following activity diagram summarises what happens when a user executes a new command. -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. +![AddActivityDiagram](images/AddActivityDiagram.png) -![UndoRedoState0](images/UndoRedoState0.png) +### Filter feature -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. +The following sequence diagram shows how the filter command works: -![UndoRedoState1](images/UndoRedoState1.png) +![FilterSequenceDiagram](images/FilterSequenceDiagram.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`. +It filters contacts by calling `Model#setContactsFilter` with a `ContainsTagPredicate predicate` as argument, which sets the `predicate` +on the list of contacts in the `ModelManager`. -![UndoRedoState2](images/UndoRedoState2.png) +### Maintaining sorting while supporting filtering -
:information_source: **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`. +The contact list is automatically kept in a constantly sorted state by leveraging `SortedList` from the JavaFX Collections library. Since the class works with `ObservableList`s, which the Model's `Contacts` also utilises, we are able to leverage this class more easily. -
+The Model obtains an unsorted, unmodifiable list from `Contacts` and wraps it in a `SortedList`. We specify an `AlphabeticalComparator` to define our own alphabetical sorting order, which takes capitalization into account. This facilitates the intended propagation of changes from the nested list to the sorted list. -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. +For operability with the find and filter feature, this sorted list is further wrapped in a `FilteredList` to limit the scope of what the user sees as needed. A dummy filter `Predicate` which allows all contacts to pass is used as the default filter. It is this filtered list that the model stores in a field. -![UndoRedoState3](images/UndoRedoState3.png) +### Edit feature -
:information_source: **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 case. If so, it will return an error to the user rather -than attempting to perform the undo. +The edit feature is facilitated by `ModelManager` and implements `Model`. -
+It is similar in implementation to the add feature, +except it edits a contact by calling `Model#updateContact`, +which replaces the old contact with the edited contact in the `UniqueContactList`. -The following sequence diagram shows how the undo operation works: +The following activity diagram summarises what happens when a user executes an edit command. -![UndoSequenceDiagram](images/UndoSequenceDiagram.png) +![EditActivityDiagram](images/EditActivityDiagram.png) -
:information_source: **Note:** The lifeline for `UndoCommand` should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram. -
+### Navigating to previous commands -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 feature of navigating between command history using the up/down arrow keys, is facilitated by `CommandBoxHistory`. `CommandBox` keeps a reference to a `CommandBoxHistory` object which stores the history of entered commands. -
: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. +`CommandBoxHistory` stores a list of commands, which behaves externally as if its last element is always the empty string. This is so that the user can enter a new command when at the last position in the command history. -
+The following sequence diagram summarises what happens when the user presses the up arrow key to navigate to the previous command in history. + +![CommandBoxHistorySequenceDiagram](images/CommandBoxHistorySequenceDiagram.png) + +The behaviour is very similar when the user presses the down arrow key to navigate to the next command in history, so we omit the corresponding sequence diagram. + +The following sequence diagram summarises what happens when the user successfully executes a new command, and this new command is stored in the command history. + +![CommandBoxHistoryNewSequenceDiagram](images/CommandBoxHistoryNewSequenceDiagram.png) + +The command is only stored in history if the execution of the command (by `CommandExecutor`) is successful. The position in history is also reset to the last position (empty string) using `CommandBoxHistory#resetPointer`. -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) +## Acknowledgements -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. +- Libraries: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) +- App icon from [McDo Design](https://www.flickr.com/photos/mcdodesign/) by Susumu Yoshida +- Some code adapted from by Marco Jakob -![UndoRedoState5](images/UndoRedoState5.png) +--- -The following activity diagram summarizes what happens when a user executes a new command: +## Appendix: Requirements - +### Product scope -#### Design considerations: +**Target user profile**: NUS SoC students, who: -**Aspect: How undo & redo executes:** +- Can type fast and prefer typing +- Are reasonably comfortable with command-line inputs +- Wish to label contacts by category (e.g. professors, classmates from certain courses, friends) +- Have many different ways to reach their contacts (e.g. social media like Telegram/Discord, additional phone numbers like house phone) -* **Alternative 1 (current choice):** Saves the entire address book. - * Pros: Easy to implement. - * Cons: May have performance issues in terms of memory usage. +**Value proposition**: Manage contacts quickly via text commands, with useful features relevant to SoC students. -* **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. +### User stories -_{more aspects and alternatives to be added}_ +Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` -### \[Proposed\] Data archiving +| Priority | As a …​ | I want to …​ | So that I can…​ | +|----------|---------------------------------|--------------------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| `* * *` | user | add contacts | keep track of my friends and schoolmates | +| `* * *` | user | delete contacts | remove my contact with that person | +| `* * *` | user | view my contacts | know who I have as contacts | +| `* * ` | user | edit contacts | make changes to my contact info when they occur | +| `* *` | user | search for contacts | find a specific contact directly and easily | +| `* *` | user | add tags to contacts | classify them based on contact type | +| `* *` | user | merge duplicate contacts | my contact list stays clean | +| `* *` | user | sort contacts by certain criteria | find contacts satisfying a certain criteria easily | +| `* *` | user | save alternate contact info for my contacts | keep track of the various ways I can contact the same person | +| `* *` | user | pin frequent contacts so they appear at the top when I open the app | access my most important contacts quickly | +| `* *` | user | indicate where I met each contact | keep track of people I have various levels of familiarity with | +| `* *` | user | view contacts by groups or type | more easily manage related contacts | +| `* *` | user | export my contacts to an external file | backup my contacts’ information | +| `* *` | user | import my contacts from an external file | quickly populate the app with my existing contacts | +| `* *` | user | clear all contacts data | quickly erase all information stored when I will no longer use the app | +| `*` | user who prefers CLI | use keyboard shortcuts | perform tasks more efficiently | +| `*` | user | see a different background colour for each contact | differentiate between contacts more easily | +| `*` | infrequent user | view a "cheatsheet" or help dialog for the text commands | remember some basic commands I may have forgotten | +| `*` | advanced user | search/filter by specific parts of contacts (e.g. containing certain words) | narrow down contacts to exactly what I am looking for | +| `*` | user who prefers CLI | switch between previously entered commands in history | easily repeat previous commands | +| `*` | busy user | use icons to denote certain contact information | identify the information I want at a glance | -_{Explain here how the data archiving feature will be implemented}_ +### Use cases +(For all use cases below, the **System** is the `ConText` and the **Actor** is the `user`, unless specified otherwise) --------------------------------------------------------------------------------------------------------------------- +**Use case: UC01 - Add a contact** -## **Documentation, logging, testing, configuration, dev-ops** +**MSS** -* [Documentation guide](Documentation.md) -* [Testing guide](Testing.md) -* [Logging guide](Logging.md) -* [Configuration guide](Configuration.md) -* [DevOps guide](DevOps.md) +1. User requests to add a contact. +2. ConText adds the contact. --------------------------------------------------------------------------------------------------------------------- + Use case ends. -## **Appendix: Requirements** +**Extensions** -### Product scope +* 1a. The given data is invalid. -**Target user profile**: + * 1a1. ConText shows an error message. -* has a need to manage a significant number of contacts -* prefer desktop apps over other types -* can type fast -* prefers typing to mouse interactions -* is reasonably comfortable using CLI apps + Use case resumes at step 1. -**Value proposition**: manage contacts faster than a typical mouse/GUI driven app +**Use case: UC02 - Delete a contact** +**MSS** -### User stories +1. User requests to view the list of contacts (UC03). +2. User requests to delete a specific contact in the list. +3. ConText deletes the contact. -Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*` + Use case ends. + +**Extensions** -| Priority | As a …​ | I want to …​ | So that I can…​ | -| -------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------------------------------- | -| `* * *` | new user | see usage instructions | refer to instructions when I forget how to use the App | -| `* * *` | user | add a new person | | -| `* * *` | user | delete a person | remove entries that I no longer need | -| `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | -| `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | -| `*` | user with many persons in the address book | sort persons by name | locate a person easily | +* 2a. An invalid contact to edit is specified. -*{More to be added}* + * 2a1. ConText shows an error message. -### Use cases + Use case resumes at step 2. + +**Use case: UC03 - List all contacts** + +**MSS** + +1. User requests to list contacts. +2. ConText shows a list of contacts. -(For all use cases below, the **System** is the `AddressBook` and the **Actor** is the `user`, unless specified otherwise) + Use case ends. -**Use case: Delete a person** +**Extensions** + +* 2a. The list is empty. + + Use case ends + +**Use case: UC04 - Edit a contact** **MSS** -1. User requests to list persons -2. AddressBook shows a list of persons -3. User requests to delete a specific person in the list -4. AddressBook deletes the person +1. User requests to view the list of contacts (UC03). +2. User requests to edit a contact. +3. ConText edits the contact. Use case ends. **Extensions** -* 2a. The list is empty. +* 2a. An invalid contact to edit is specified. + + * 2a1. ConText shows an error message. + + Use case resumes at step 2. + +* 2b. The given data is incorrect. + + * 2b1. ConText shows an error message. + + Use case resumes at step 2. + +**Use case: UC05 - Clear all contacts** + +**MSS** + +1. User requests to clear all contacts. +2. ConText clears all contacts. + + Use case ends. + +**Use case: UC06 - Find a contact** + +**MSS** + +1. User requests to find a contact. +2. ConText displays a list of contacts matching the given data. + + Use case ends. + +**Extensions** + +* 2a. The filtered list is empty. Use case ends. -* 3a. The given index is invalid. +**Use case: UC07 - Filter tags** + +**MSS** - * 3a1. AddressBook shows an error message. +1. User requests to filter the list of contacts by a given tag. +2. ConText displays a filtered list of contacts based on the given tag. - Use case resumes at step 2. + Use case ends. -*{More to be added}* +**Extensions** -### Non-Functional Requirements +* 2a. The filtered list is empty. -1. Should work on any _mainstream OS_ as long as it has Java `11` or above installed. -2. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. -3. 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. + Use case ends. -*{More to be added}* +### Non-functional requirements + +1. "Brownfield" - Changes to the codebase must be done in small increments. +1. "Typing preferred" - The product must target users who can type fast and prefer CLI as their means of input. +1. "Single user" - The product must be designed for a single user. +1. "Incremental" - The product must be developed breadth-first as well as consistently each week. +1. "Human editable file" - Data must be stored locally in a human-editable text file format. +1. "No DBMS" - DataBase Management Systems must not be used. +1. "OO" - Software must mostly follow the object-oriented paradigm. +1. "Platform independent" - Software must work on Windows, Linux, and OSX. I.e., avoid OS-dependent libraries and OS-specific features. +1. "Java version" - Software must work on a computer that has Java version 11 installed. +1. "Portable" - Software must work without requiring an installer. +1. "No remote server" - Software must not depend on a remote server. +1. "External software" - Any 3rd party frameworks/libraries/services used must: + 1. Be free and open-source (except services), with permissive license terms (e.g. non-time limited trial). + 1. Not require installation by users. Services that require account creation on their 3rd party service are strongly discouraged. + 1. Not violate other project constraints. + 1. Be approved by the teaching team. +1. "Screen resolution" - GUI must work well for standard screen resolutions and scales, as specified in the admin info. GUI must still be usable if those factors are non-standard. +1. "Single file" - Software must all be packed into a single JAR file. +1. "File size" - Software must not exceed 100MB and must not be unnecessarily bloated. Documents must not exceed 15MB per file. +1. "PDF-friendly" - Developer and user guides must be PDF-friendly, without using expandable panels, embedded videos, animated GIFs etc. +1. "Minimal network" - Any public APIs used should have a fallback mechanism in the event that they are down. Any NUS data used should have the approval of NUS IT. +1. "Testability" - Features should not be hard to test or make the product hard to test, be the testing manual or automated. +1. "CLI first" - Users who can type fast should be able to accomplish most tasks faster via the CLI as compared to if they were to use a hypothetical GUI-only version of the product. +1. There must exist an image with the exact name and format `docs/images/Ui.png` depicting the final product, with similar proportions as the original AB3 image. +1. There must exist an `AboutUs` page that closely follows the original template, such that CS2103 grading scripts can understand it. + 1. Each team member must have an appropriately named lowercase PNG of their profile picture, as specified in the admin info. +1. There must exist Project Portfolio Pages (PPPs) in `docs/team/`, containing sections specified in the admin info. + 1. Each team member must have their own appropriately named lowercase page file, as specified in the admin info. + 1. The page must be written to account for paged PDF conversion. +1. Documentation must be built using Jekyll or MarkBind, then hosted via GitHub Pages, such that they are compatible with CS2103 grading scripts. +1. Branches must not be deleted after their associated PRs have been merged, so that CS2103 grading scripts can detect that the correct workflow was used. +1. The `README.md` must acknowledge SE-EDU's AB3, which this project is based on. It should also contain the `Ui.png`, as well as the repo's GitHub Actions build status badge. ### Glossary -* **Mainstream OS**: Windows, Linux, Unix, OS-X -* **Private contact detail**: A contact detail that is not meant to be shared with others +* **Architecture Diagram**: A visual representation that depicts the high-level design and structure of the software application. + +* **Component**: A modular part of the system with a distinct responsibility. The main components mentioned are UI, Logic, Model, and Storage. + +* **Commons**: Classes or utilities used by multiple components of the application. + +* **UI (User Interface)**: The space where interactions between humans and the software occur. The goal of this interaction is to allow effective operation and control of the machine from the human end. + +* **GUI (Graphical User Interface)**: A type of user interface that allows users to interact with electronic devices through graphical elements such as images, buttons, icons, and windows instead of text-based command lines. + +* **Logic**: In the context of software, it refers to the set of rules and algorithms that process and respond to user inputs. + +* **Model**: The part of the application that manages data and application logic. + +* **Storage**: The part of the application responsible for saving and loading data to and from persistent storage. + +* **API (Application Programming Interface)**: A set of rules and tools that allows different software applications to communicate with each other. In this context, it refers to the interfaces defined for each component, such as `Logic.java`, `Model.java`, etc. + +* **Sequence Diagram**: A type of UML diagram that shows how objects interact in a specific order. --------------------------------------------------------------------------------------------------------------------- +* **UML (Unified Modeling Language)**: A standardized modeling language enabling developers to specify, visualize, construct, and document artifacts of a software system. -## **Appendix: Instructions for manual testing** +* **PlantUML**: A tool that allows users to create UML diagrams using a simple and intuitive language. + +* **`puml` files**: Files written in a text-based markup language used by PlantUML to generate UML diagrams. + +* **MSS (Main Success Scenario)**: Represents the sequence of steps that describe a successful execution of a use case. + +* **CLI (Command Line Interface)**: A user interface that allows users to interact with the software by typing text-based commands. + +* **JavaFX**: A Java library used to create desktop applications. It is used for designing the user interface of this application. + +* **ObservableList**: A list that allows listeners to track changes when they occur. Used in the context of JavaFX to automatically update the UI when the data changes. + +* **JSON (JavaScript Object Notation)**: A lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. Used for storing data in this application. + +* **JUnit**: A testing framework for Java programming language. JUnit5 refers to the fifth major version of this framework. + +* **Predicate**: A functional interface that represents a condition (test) and is used to filter data. + +* **Brownfield**: A term used in software development to describe a project that has existing constraints, typically an existing system or codebase, as opposed to a greenfield project which starts from scratch. + +* **Platform independent**: Software that can run on any computer regardless of its operating system, such as Mac/Windows/Linux. + +* **Human editable file**: A file format designed to be easily readable and editable by humans. + +* **Portable**: Software that doesn't require installation and can be run from any location, such as from a USB stick. + +--- + +## Appendix: Instructions for manual testing Given below are instructions to test the app manually. -
:information_source: **Note:** These instructions only provide a starting point for testers to work on; +
+:information_source: **Note:** These instructions only provide a starting point for testers to work on; testers are expected to do more *exploratory* testing. -
### Launch and shutdown 1. Initial launch - 1. Download the jar file and copy into an empty folder + 1. Download the jar file and place it into an empty folder + + 1. Open a command terminal, `cd` into the folder you put the JAR file in, and use the `java -jar context.jar` command to run the app. + +### Adding a new contact + +1. Adding a contact with all fields + + 1. Test case: `add n/John Doe p/12345678 e/john@example.com o/notes t/friend a/Telegram: johndoe` + Expected: A new contact with the name "John Doe", phone number "12345678", email "john@example.com", a note "notes", tagged as "friend", and an alternate contact "Telegram: johndoe" is added to the list. + + 1. Test case: `add n/Alice p/87654321 e/alice@example.com` + Expected: A new contact with the name "Alice", phone number "87654321", and email "alice@example.com" is added. Optional fields are left blank. + + 1. Other incorrect add commands to try: `add`, `add n/John Doe`, `add e/john@example.com`, `add n/John Doe p/12`
+ Expected: Error message indicating the correct format for the `add` command. + +### Editing an existing contact - 1. Double-click the jar file Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. +1. Editing a contact's name and email -1. Saving window preferences + 1. Prerequisites: Have at least one contact in the list. - 1. Resize the window to an optimum size. Move the window to a different location. Close the window. + 1. Test case: `edit 1 n/Jane Doe e/jane@example.com` + Expected: The first contact in the list has its name changed to "Jane Doe" and email to "jane@example.com". - 1. Re-launch the app by double-clicking the jar file.
- Expected: The most recent window size and location is retained. + 1. Test case: `edit 1 t/` + Expected: All of the existing tags of the first contact in the list are removed while other information of the contact remains unchanged. -1. _{ more test cases …​ }_ + 1. Test case: `edit 2 n/Bob` + Expected: Error message indicating the correct format for the `edit` command. -### Deleting a person + 1. Other incorrect edit commands to try: `edit`, `edit x` (where x is larger than the number of contacts in ConText), `edit 1 n/`, `edit 1 e/`
+ Expected: Error message indicating the correct or valid usage of the `edit` command. -1. Deleting a person while all persons are being shown +### Deleting a contact - 1. Prerequisites: List all persons using the `list` command. Multiple persons in the list. +1. Deleting a contact while all contacts are being shown + + 1. Prerequisites: List all contacts using the `list` command. Multiple contacts 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 0`
- Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. + Expected: No contact is deleted. Error details shown in the status message. Status bar remains the same. + + 1. Test case: `delete 1 2 3`
+ Expected: First, second, and third contacts are deleted from the list. Details of the deleted contacts shown in the status message. Timestamp in the status bar is updated. + + 1. Test case: `delete 1 1 2`
+ Expected: First and second contacts are deleted from the list without duplication. Details of the deleted contacts shown in the status message. Timestamp in the status bar is updated. 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 …​ }_ +### Filtering contacts by tag + +1. Filtering contacts using a specific tag + + 1. Test case: `filter friend` + Expected: List all contacts tagged as "friend". + + 1. Other incorrect filter commands to try: `filter`, `filter @#$%` (assuming no such tags)
+ Expected: Error message indicating the correct usage of the `filter` command or no contacts found message. ### Saving data 1. Dealing with missing/corrupted data files - 1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_ - -1. _{ more test cases …​ }_ + 1. Test case: Navigate to the folder with the JAR file, and remove all files and subfolders except the JAR file. Relaunch the app. + Expected: The app will launch normally, with sample contact data. + + 1. Test case: Navigate to the folder with the JAR file, and make arbitrary changes to the `\data\contacts.json` file, so as to render it invalid. Relaunch the app. + Expected: The app will launch normally, with an empty contact list. + +## Appendix: Planned enhancements + +1. Currently, error messages displayed in ConText are generic. +For example, if a user enters a negative index, the error message `Invalid command format` is displayed, even if the command format is technically correct. +We plan to add more specific error messages for invalid indices (e.g. non-positive, too large, or does not exist in the list), to let the user know that the index itself is invalid, and why. + +1. Currently, special characters such as `-` and `/` are not allowed in names, even though they could conceivably be part of a contact's legal name. +We plan to allow for special characters to be included in a contact's name. + +1. Currently, the `find` command only allows for matching of full words. +For example, the input keyword `John` will not match the name `Johnny` stored in the list. +This may lead to unintended behaviour for some users. We plan to allow partial matches of contact names for `find`. + +1. Currently, duplicate contacts are only detected by contacts having completely identical names, and not by other fields such as email address. +Although this is meant to remove ambiguity in duplicate detection, it may be counter-intuitive for some users. +We plan to include additional warning messages for the detection of duplicate contacts. +We will warn users if they are adding contacts with duplicate information, such as duplicate email address, or names which differ only by whitespace (in the middle). +The user can then confirm whether they would like the duplicate contact to go through, or whether they would like to make changes to the duplicate contact. + +1. Currently, duplicate values for deletion indices, as well as parameters like `t/` and `a/`, get silently merged. +This is not outright rejected for the convenience of users. +However, users may have accidentally entered such duplicate values, which may result in the app's behaviour differing from users' expectations. +In such cases, we plan to display additional warning messages for commands like `add`, `edit`, and `delete`, so that users may check if their specifying of duplicate values is intentional. +Users may then press enter again to confirm the command's execution, or edit the command. + +1. Currently, if no note (i.e. no `o/` parameter) is specified when adding a contact, the note's value defaults to being empty (`""`). +The UI accounts for empty notes by not taking up an extra line to display the empty note. +When users do specify a note, they may explicitly specify an empty note (i.e. `o/` with no value). +This is not outright rejected for the convenience of users, since empty notes are allowed. +However, users may have forgotten to specify a value for the note, which may result in the app's behaviour differing from users' expectations. +In such cases, we plan to display an additional warning message for commands like `add`, so that users may check if their specifying of empty notes is intentional. + +1. Currently, users are allowed to enter very flexible phone number values. +The only validation requirement is that the phone number begins with 3 digits. +This allows users to use the feature as they wish. +For example, although the standard intended usage is for users to enter just the digits of a phone number (e.g. `98765432`), they are also allowed to enter a value such as `65432109 (office); 98765432 (mobile)`. +However, this flexibility may result in users accidentally entering invalid phone numbers, such as `9876p/5432`. +Therefore, if users enter a phone number that does not contain only 3-15 digits, we plan to display an additional warning message for commands like `add` and `edit`, so that users may check if their specifying of such a value is intentional. +Users may then press enter again to confirm the command's execution, or edit the command. +The added need to confirm non-standard phone numbers nudges users towards using the alternate contacts feature for additional phone numbers instead. + +1. Currently, alternate contacts do not allow spaces in the "type" portion, and do not allow special characters such as `@` in the "username" portion. +We plan to allow spaces in the "type" portion for added flexibility. +We also plan to allow special characters in the "username" portion, by allowing username values which match existing phone number/email validation. +Similarly, we would also allow all phone numbers to optionally start with the special character `+` before the required digits. diff --git a/docs/Documentation.md b/docs/Documentation.md deleted file mode 100644 index 3e68ea364e7..00000000000 --- a/docs/Documentation.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: page -title: Documentation guide ---- - -**Setting up and maintaining the project website:** - -* We use [**Jekyll**](https://jekyllrb.com/) to manage documentation. -* The `docs/` folder is used for documentation. -* To learn how set it up and maintain the project website, follow the guide [_[se-edu/guides] **Using Jekyll for project documentation**_](https://se-education.org/guides/tutorials/jekyll.html). -* Note these points when adapting the documentation to a different project/product: - * The 'Site-wide settings' section of the page linked above has information on how to update site-wide elements such as the top navigation bar. - * :bulb: In addition to updating content files, you might have to update the config files `docs\_config.yml` and `docs\_sass\minima\_base.scss` (which contains a reference to `AB-3` that comes into play when converting documentation pages to PDF format). -* If you are using Intellij for editing documentation files, you can consider enabling 'soft wrapping' for `*.md` files, as explained in [_[se-edu/guides] **Intellij IDEA: Useful settings**_](https://se-education.org/guides/tutorials/intellijUsefulSettings.html#enabling-soft-wrapping) - - -**Style guidance:** - -* Follow the [**_Google developer documentation style guide_**](https://developers.google.com/style). - -* Also relevant is the [_[se-edu/guides] **Markdown coding standard**_](https://se-education.org/guides/conventions/markdown.html) - -**Diagrams:** - -* See the [_[se-edu/guides] **Using PlantUML**_](https://se-education.org/guides/tutorials/plantUml.html) - -**Converting a document to the PDF format:** - -* See the guide [_[se-edu/guides] **Saving web documents as PDF files**_](https://se-education.org/guides/tutorials/savingPdf.html) diff --git a/docs/Logging.md b/docs/Logging.md deleted file mode 100644 index 5e4fb9bc217..00000000000 --- a/docs/Logging.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: page -title: Logging guide ---- - -* We are using `java.util.logging` package for logging. -* The `LogsCenter` class is used to manage the logging levels and logging destinations. -* The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level. -* Log messages are output through the console and to a `.log` file. -* The output logging level can be controlled using the `logLevel` setting in the configuration file (See the [Configuration guide](Configuration.md) section). -* **When choosing a level for a log message**, follow the conventions given in [_[se-edu/guides] Java: Logging conventions_](https://se-education.org/guides/conventions/java/logging.html). diff --git a/docs/SettingUp.md b/docs/SettingUp.md deleted file mode 100644 index 275445bd551..00000000000 --- a/docs/SettingUp.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -layout: page -title: Setting up and getting started ---- - -* Table of Contents -{:toc} - - --------------------------------------------------------------------------------------------------------------------- - -## Setting up the project in your computer - -
:exclamation: **Caution:** - -Follow the steps in the following guide precisely. Things will not work out if you deviate in some steps. -
- -First, **fork** this repo, and **clone** the fork into your computer. - -If you plan to use Intellij IDEA (highly recommended): -1. **Configure the JDK**: Follow the guide [_[se-edu/guides] IDEA: Configuring the JDK_](https://se-education.org/guides/tutorials/intellijJdk.html) to to ensure Intellij is configured to use **JDK 11**. -1. **Import the project as a Gradle project**: Follow the guide [_[se-edu/guides] IDEA: Importing a Gradle project_](https://se-education.org/guides/tutorials/intellijImportGradleProject.html) to import the project into IDEA.
- :exclamation: Note: Importing a Gradle project is slightly different from importing a normal Java project. -1. **Verify the setup**: - 1. Run the `seedu.address.Main` and try a few commands. - 1. [Run the tests](Testing.md) to ensure they all pass. - --------------------------------------------------------------------------------------------------------------------- - -## Before writing code - -1. **Configure the coding style** - - If using IDEA, follow the guide [_[se-edu/guides] IDEA: Configuring the code style_](https://se-education.org/guides/tutorials/intellijCodeStyle.html) to set up IDEA's coding style to match ours. - -
:bulb: **Tip:** - - Optionally, you can follow the guide [_[se-edu/guides] Using Checkstyle_](https://se-education.org/guides/tutorials/checkstyle.html) to find how to use the CheckStyle within IDEA e.g., to report problems _as_ you write code. -
- -1. **Set up CI** - - This project comes with a GitHub Actions config files (in `.github/workflows` folder). When GitHub detects those files, it will run the CI for your project automatically at each push to the `master` branch or to any PR. No set up required. - -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). - -1. **Do the tutorials** - These tutorials will help you get acquainted with the codebase. - - * [Tracing code](tutorials/TracingCode.md) - * [Adding a new command](tutorials/AddRemark.md) - * [Removing fields](tutorials/RemovingFields.md) diff --git a/docs/Testing.md b/docs/Testing.md deleted file mode 100644 index 8a99e82438a..00000000000 --- a/docs/Testing.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -layout: page -title: Testing guide ---- - -* Table of Contents -{:toc} - --------------------------------------------------------------------------------------------------------------------- - -## Running tests - -There are two ways to run tests. - -* **Method 1: Using IntelliJ JUnit test runner** - * To run all tests, right-click on the `src/test/java` folder and choose `Run 'All Tests'` - * To run a subset of tests, you can right-click on a test package, - test class, or a test and choose `Run 'ABC'` -* **Method 2: Using Gradle** - * Open a console and run the command `gradlew clean test` (Mac/Linux: `./gradlew clean test`) - -
:link: **Link**: Read [this Gradle Tutorial from the se-edu/guides](https://se-education.org/guides/tutorials/gradle.html) to learn more about using Gradle. -
- --------------------------------------------------------------------------------------------------------------------- - -## Types of tests - -This project has three types of tests: - -1. *Unit tests* targeting the lowest level methods/classes.
- e.g. `seedu.address.commons.StringUtilTest` -1. *Integration tests* that are checking the integration of multiple code units (those code units are assumed to be working).
- e.g. `seedu.address.storage.StorageManagerTest` -1. Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
- e.g. `seedu.address.logic.LogicManagerTest` diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 57437026c7b..fb635a2dbe4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -3,195 +3,323 @@ layout: page title: User Guide --- -AddressBook Level 3 (AB3) 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. +**ConText** is a desktop app that allows for managing contacts quickly via text commands. +It is optimized for use via an in-app Command Line Interface (CLI), while still having the benefits of a Graphical User Interface (GUI). -* Table of Contents +It has useful features relevant to NUS SoC students: + +- Tagging contacts by category: You can tag your professors and classmates with custom tags such as "prof", "friend", "CS2103 course" etc., then filter by tag to view all contacts with a certain tag. +- Storing different ways to reach people: By adding alternate contact details, you could have Telegram, Discord, mobile phone, house phone etc. all in the same contact. +- Works like a usual CLI: You can use the up/down arrow keys to switch between previously-entered commands, making entering and repeating commands (e.g. adding many new contacts) easier. + +If you can type fast, prefer typing, and are reasonably comfortable with CLI inputs, ConText can let you manage contacts faster than traditional GUI apps. + +- Table of Contents {:toc} --------------------------------------------------------------------------------------------------------------------- +--- ## Quick start -1. Ensure you have Java `11` or above installed in your Computer. +1. Ensure you have [Java 11](https://openjdk.org/) or above installed. -1. Download the latest `addressbook.jar` from [here](https://github.com/se-edu/addressbook-level3/releases). +1. Download the latest `context.jar` [here](https://github.com/AY2324S1-CS2103-W14-3/tp/releases). -1. Copy the file to the folder you want to use as the _home folder_ for your AddressBook. +1. Place the JAR file in the folder you want to use as the app's home folder. -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.
- A GUI similar to the below should appear in a few seconds. Note how the app contains some sample data.
- ![Ui](images/Ui.png) +1. Open a command terminal, `cd` into the folder you put the JAR file in, and use the `java -jar context.jar` command to run the application.\ +A window should open with a GUI similar to the one below. Note how the app starts off with some sample data.\ +![Ui](images/Ui.png) -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: +1. The text box at the top of the window should be automatically selected. This is where you can type your text commands. Press Enter to execute them.\ +The feedback from each command's execution will be displayed below the text box, with the currently displayed list of contacts below that. - * `list` : Lists all contacts. +1. Refer to the [Features](#features) section below to find out about the various commands. - * `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. +
+:bulb: **Tip:** +You could test out some commands on the sample data. +Once you are familiarised, feel free to use the `clear` command to delete all the sample data, and start adding your own contacts! +
- * `delete 3` : Deletes the 3rd contact shown in the current list. +--- - * `clear` : Deletes all contacts. +## Features - * `exit` : Exits the app. +At a glance: the information that can be stored with each contact, and how it will appear in the application, is labelled below. -1. Refer to the [Features](#features) below for details of each command. +![ContactCard](images/ContactCard.png) --------------------------------------------------------------------------------------------------------------------- +
+**:information_source: About the command format:**
-## Features +- Some commands take in parameters. +e.g. in `add n/NAME`, the `add` command takes in an `n/` parameter. + +- Words in `UPPER_CASE` are placeholders for values to be specified.
+e.g. in `edit INDEX`, you should specify an `INDEX` such as `edit 1`.
+e.g. in `add n/NAME`, you should specify a `NAME` such as `add n/John Doe`. + +- Parameters in square brackets are optional.
+e.g in `n/NAME [o/NOTE]`, you could specify `n/John Doe o/Good at SE.`, or just `n/John Doe`. + + +- Parameters with `…`​ after them can be specified multiple times.
+e.g. in `[t/TAG]…​`, which is optional but can also be specified multiple times, you could specify ` ` (none specified), `t/NUS`, `t/NUS t/CS2103 course` etc. + +- Parameters can be specified in any order.
+e.g. in `n/NAME p/PHONE_NUMBER`, the order `p/PHONE_NUMBER n/NAME` also works. + +- Extra words for commands that do not take any parameters (such as `list` or `help`) will be ignored.
+e.g. `list 10 n/John Doe z/Extra` will be interpreted as just `list`. + +- If you are using the PDF version of this user guide, be careful when copy-pasting commands that span multiple lines. Spaces surrounding line breaks may get omitted when copied over to the app. +
+ +### Adding a contact: `add` + +Adds a new contact. + +Note that contacts are identified by their name in ConText, and contacts with exactly the same name (including casing) are considered the same contact. +Hence, you will not be able to add a new contact with the same name as an existing contact. + +For example, if you already have a contact with name `John Doe`, you will not be able to add another contact with the same name `John Doe`. +For two names to be considered the same, they must be identical in every way, and that includes casing, as well as whitespace in the middle of the name, etc. +Therefore, you may add another contact with name `John doe`, `John Doe`, or `Alex John Doe`. +You may also first modify the name of the existing contact. + +Should you need to make changes to an existing contact, use the `edit` command as explained below. + +**Format:** +`add n/NAME p/PHONE_NUMBER e/EMAIL [o/NOTE] [t/TAG]... [a/ALTERNATE_CONTACT]...` + +
+:information_source: **About phone number** +Phone numbers must contain at least 3 digits. You can add extra information after digits for you to keep track of what the number is for. +For additional phone numbers, please make use of `ALTERNATE_CONTACT` +
+:information_source: **About tags:** + +- Duplicate tags are only counted once. +- Specifying empty tags (`t/` with no value) is not allowed when adding contacts. If you wish to specify no tags, you may simply leave out the `t/` parameter. +
+ +
+:information_source: **About the alternate contact format:** +- The format for `ALTERNATE_CONTACT` is `TYPE: USERNAME`, roughly looking like `SocialMedia: Username`. Ensure to include a space between the colon `:` and the `Username`. +- Do note at this moment whitespace is not supported for `TYPE` and `USERNAME`. `USERNAME` only supports alphanumerics and some special characters `.`, `_` and `-`. +- Specifying empty alternate contacts (`a/` with no value) is not allowed when adding contacts. If you wish to specify no alternate contacts, you may simply leave out the `a/` parameter. +
-**:information_source: Notes about the command format:**
-* Words in `UPPER_CASE` are the parameters to be supplied by the user.
- e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. -* Items in square brackets are optional.
- e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. +**Examples:** -* Items with `…`​ after them can be used multiple times including zero times.
- e.g. `[t/TAG]…​` can be used as ` ` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. +- `add n/John Doe p/98765432 e/john.doe@email.com` +(Adds a contact with the name `John Doe`, phone `98765432` and email `john.doe@email.com`) +- `add n/John Doe p/98765432 e/john.doe@email.com o/Likes SE. t/NUS t/CS2103 course a/Telegram: JohnDoe` +(Adds a contact with the name `John Doe`, phone `98765432`, email `john.doe@email.com`, note `Likes SE.`, tags `NUS` and `CS2103 course` and alternate contact `Telegram: JohnDoe`) -* 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. +### Editing a contact: `edit` -* 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`. +Edits an existing contact at the specified `INDEX`. -* If you are using a PDF version of this document, be careful when copying and pasting commands that span multiple lines as space characters surrounding line-breaks may be omitted when copied over to the application. +**Format:** +`edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [o/NOTE] [t/TAG]... [a/ALTERNATE_CONTACT]...` + +
+:information_source: **About index numbers:** +`INDEX` refers to the index number currently shown in the displayed contact list (#1, #2, #3 etc.). +Indices must be a positive integer to be valid (1, 2, 3 etc.), and must exist in the displayed contact list. +Contacts are 1-indexed, that is, the first contact has index number 1. Index number 0 is not valid. +
+ +
+:information_source: **About phone/tags/the alternate contact format:** +Please refer to the [above](#adding-a-contact-add).
-### Viewing help : `help` +- At least one of the optional parameters must be specified. -Shows a message explaning how to access the help page. +- Each specified parameter will have its new value(s) replace all existing value(s) for that parameter.\ +e.g. `edit 1 n/The Myth` will edit the name of contact #`1` to `The Myth`, without changing any other parameter values for that contact. + - When editing tags, the new specified tag(s) will similarly replace all existing tag(s).\ + You can specify no tags (i.e. clear all tags) via a _single_ `t/` without a value. + - Likewise, when editing alternate contacts, you can specify no alternate contacts (i.e. clear all alternate contacts) via a _single_ `a/` without a value. -![help message](images/helpMessage.png) +**Examples:** -Format: `help` +- `edit 1 p/87654321 e/jane_doe@nus.edu.sg` +(Edits the phone number and email address of contact #`1` to `87654321` and `jane_doe@nus.edu.sg` respectively.) +- `edit 3 o/Member of NUS S/U t/` (Edits the note of contact #`3` to `Member of NUS S/U` and clears any of its existing tags.) -### Adding a person: `add` +### Deleting contacts: `delete` -Adds a person to the address book. +Deletes the contact(s) at the specified `INDEX` or indices. -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​` +**Format:** +`delete INDEX...` -
:bulb: **Tip:** -A person can have any number of tags (including 0) +
+:information_source: **About index numbers:** +Please refer to the [above](#editing-a-contact-edit).
-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` +- You can delete multiple contacts at once by specifying multiple indices separated by spaces. + +- Duplicate indices are only counted once.\ +e.g. `delete 1 1` will only delete the contact at index #`1`. +- Invalid indices will cause abortion of the delete command. -### Listing all persons : `list` -Shows a list of all persons in the address book. +**Examples:** -Format: `list` +- `delete 1` +(Deletes the contact at index #`1`.) -### Editing a person : `edit` +- `delete 1 3 5` +(Deletes the contacts at indices #`1`, #`3`, and #`5`.) -Edits an existing person in the address book. +### Clearing all contacts: `clear` -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]…​` +
+:exclamation: **Caution:** +This command will immediately delete all your contacts. **Use with care!** +
-* 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, …​ -* 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 - specifying any tags after it. +**Format:** +`clear` -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. +### Listing all contacts: `list` -### Locating persons by name: `find` +Shows all contacts. -Finds persons whose names contain any of the given keywords. +**Format:** +`list` -Format: `find KEYWORD [MORE_KEYWORDS]` +### Finding by name: `find` -* 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). - e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +Shows contacts whose names have a word that fully matches any of the specified keywords. -Examples: -* `find John` returns `john` and `John Doe` -* `find alex david` returns `Alex Yeoh`, `David Li`
- ![result for 'find alex david'](images/findAlexDavidResult.png) +**Format:** +`find KEYWORD...` -### Deleting a person : `delete` +- The search is case-insensitive.\ +e.g. Keyword `john` will match the name `John`. -Deletes the specified person from the address book. +- The order of the keywords does not matter.\ +e.g. Keywords `Amy John` will show the same contacts as keywords `John Amy`. -Format: `delete INDEX` +- Only full words will be matched.\ +e.g. Keyword `John` will not match the names `Johnny` or `Jo`. -* Deletes 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, …​ +- Each name only needs one word to fully match at least one keyword (i.e. `OR` search).\ +e.g. `find Bee John` will match the names `Amy Bee` and `John Doe`. -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. +**Examples:** -### Clearing all entries : `clear` +- `find John` +- `find amy Ben CHARLOTTE` -Clears all entries from the address book. +### Filtering by tag: `filter` -Format: `clear` +Shows contacts with a tag that fully matches the specified tag (case-insensitive). -### Exiting the program : `exit` +**Format:** +`filter TAG` -Exits the program. +- The search is case-insensitive.\ + e.g. `filter friend` will match the tag `Friend`. -Format: `exit` +- Only full tags will be matched.\ + e.g. `filter Fri` will _not_ match the tag `Friend`.\ + e.g. `filter Friend` will _not_ match the tag `Close Friend`. -### Saving the data +- The keyword can contain spaces.\ + e.g. `filter Close Friend` will match the tag `Close Friend` (and this tag only).\ + e.g. `filter Close⠀⠀⠀⠀⠀⠀⠀⠀Friend` will _not_ match the tag `Close Friend`. -AddressBook data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually. +- In summary, `filter` looks for tags which are an exact match, ignoring casing only. -### Editing the data file +**Examples:** -AddressBook data are saved automatically as a JSON file `[JAR file location]/data/addressbook.json`. Advanced users are welcome to update data directly by editing that data file. +- `filter NUS` +- `filter CS2103 course` -
:exclamation: **Caution:** -If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it. -
+### Viewing help: `help` + +Opens a subwindow with a convenient link to the user guide. + +**Format:** +`help` + +Alternatively, you can press F1 or click Help → Help in the top toolbar. + +### Exiting the app: `exit` + +Exits the app. + +**Format:** +`exit` + +Alternatively, you can click File → Exit in the top toolbar. -### Archiving data files `[coming in v2.0]` +### Automatic sorting -_Details coming soon ..._ +The displayed contact list is always automatically sorted in ascending alphabetical order, regardless of capitalization. --------------------------------------------------------------------------------------------------------------------- +### Automatic saving +Your contacts get automatically saved to the file system after each successful command execution. There is no need to save manually. + +### Editing the data file + +ConText data are saved automatically as a JSON file `[JAR file location]/data/contacts.json`. Advanced users are welcome to update data directly by editing that data file. + +
:exclamation: **Caution:** +If your changes to the data file make its format invalid, ConText will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it. +
+ +--- ## 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 AddressBook 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 ConText home folder. --------------------------------------------------------------------------------------------------------------------- +--- -## Known issues +## Command summary -1. **When using multiple screens**, if you move the application to a secondary screen, and later switch to using only the primary screen, the GUI will open off-screen. The remedy is to delete the `preferences.json` file created by the application before running the application again. +| Action | Command Format | Example Usage | +|-------------------|-------------------------------------------------------------------------|--------------------------------------------------------------------| +| Adding a contact | `add n/NAME p/PHONE_NUMBER e/EMAIL [o/NOTE] [t/TAG]... [a/ALTERNATE_CONTACT]...` | `add n/John Doe p/98765432 e/john.doe@email.com` | +| | | `add n/John Doe p/98765432 e/john.doe@email.com o/Likes SE. t/NUS t/CS2103 course a/Telegram: JohnDoe` | +| Editing a contact | `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [o/NOTE] [t/TAG]... [a/ALTERNATE_CONTACT]...` | `edit 1 p/87654321 e/jane_doe@nus.edu.sg` | +| | | `edit 3 o/Member of NUS S/U t/` | +| Deleting contacts | `delete INDEX...` | `delete 1` | +| | | `delete 1 3 5` | +| Clearing all contacts | `clear` | `clear` | +| Listing all contacts | `list` | `list` | +| Finding by name | `find KEYWORD...` | `find John` | +| | | `find amy Ben CHARLOTTE` | +| Filtering by tag | `filter TAG` | `filter NUS` | +| | | `filter CS2103 course` | +| Viewing help | `help` | `help` | +| Exiting the app | `exit` | `exit` | --------------------------------------------------------------------------------------------------------------------- -## Command summary +--- + +## Known limitations + +1. **Long contact details are not in the product's scope.**\ +e.g. names/phone numbers/emails/notes/tags/alternate contacts with hundreds of characters.\ +Such long text is likely to get shortened with ellipses (`...`) or cut off by the app's window.\ +You may try to remedy this by resizing the app's window to be wider. -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` -**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` -**Find** | `find KEYWORD [MORE_KEYWORDS]`
e.g., `find James Jake` -**List** | `list` -**Help** | `help` +1. **Multiple monitors are not in the product's scope.**\ +When using multiple monitors, if you move the app's window to a secondary monitor, then later switch to using just the primary monitor, the GUI will reopen off-screen.\ +You can remedy this by deleting the `settings.json` file created by the app before running the app again. diff --git a/docs/_config.yml b/docs/_config.yml index 6bd245d8f4e..81a9fdb89c9 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ -title: "AB-3" +title: "ConText" theme: minima header_pages: @@ -8,7 +8,7 @@ header_pages: markdown: kramdown -repository: "se-edu/addressbook-level3" +repository: "AY2324S1-CS2103-W14-3/tp" github_icon: "images/github-icon.png" plugins: diff --git a/docs/_sass/minima/_base.scss b/docs/_sass/minima/_base.scss index 0d3f6e80ced..8ade2f397d9 100644 --- a/docs/_sass/minima/_base.scss +++ b/docs/_sass/minima/_base.scss @@ -288,8 +288,7 @@ table { text-align: center; } .site-header:before { - content: "AB-3"; + content: "ConText"; font-size: 32px; } } - diff --git a/docs/_sass/minima/custom-styles.scss b/docs/_sass/minima/custom-styles.scss index 56b5d56b430..08da042ebf0 100644 --- a/docs/_sass/minima/custom-styles.scss +++ b/docs/_sass/minima/custom-styles.scss @@ -31,4 +31,3 @@ h2, h3, h4, h5, h6 { @include alert-variant(color-level($value, $alert-bg-level), color-level($value, $alert-border-level), color-level($value, $alert-color-level)); } } - diff --git a/docs/diagrams/CommitActivityDiagram.puml b/docs/diagrams/AddActivityDiagram.puml similarity index 68% rename from docs/diagrams/CommitActivityDiagram.puml rename to docs/diagrams/AddActivityDiagram.puml index 8c0892d6a70..ded4ac4b932 100644 --- a/docs/diagrams/CommitActivityDiagram.puml +++ b/docs/diagrams/AddActivityDiagram.puml @@ -5,13 +5,13 @@ skinparam ArrowFontSize 12 start :User executes command; +:Contact object is created; + 'Since the beta syntax does not support placing the condition outside the 'diamond we place it as the true branch instead. - -if () then ([command commits AddressBook]) - :Purge redundant states; - :Save AddressBook to - addressBookStateList; +if () then ([Contact object is unique]) + :Save Contact to + UniqueContactList; else ([else]) endif stop diff --git a/docs/diagrams/AddSequenceDiagram.puml b/docs/diagrams/AddSequenceDiagram.puml new file mode 100644 index 00000000000..e838536c8e0 --- /dev/null +++ b/docs/diagrams/AddSequenceDiagram.puml @@ -0,0 +1,78 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":InputParser" as InputParser LOGIC_COLOR +participant ":AddCommandParser" as AddCommandParser LOGIC_COLOR +participant "a:AddCommand" as AddCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +participant "contact:Contact" as Contact MODEL_COLOR +end box + +[-> LogicManager : execute("add n/Alice ...") +activate LogicManager + +LogicManager -> InputParser : parseCommand("add n/Alice ...") +activate InputParser + +create AddCommandParser +InputParser -> AddCommandParser +activate AddCommandParser + +AddCommandParser --> InputParser +deactivate AddCommandParser + +InputParser -> AddCommandParser : parse("n/Alice ...") +activate AddCommandParser + + + +create Contact +AddCommandParser -> Contact +activate Contact + +Contact --> AddCommandParser : contact +deactivate Contact + +create AddCommand +AddCommandParser -> AddCommand +activate AddCommand + +AddCommand --> AddCommandParser : a +deactivate AddCommand + +AddCommandParser --> InputParser : a +deactivate AddCommandParser + +InputParser --> LogicManager : a +deactivate InputParser + +LogicManager -> AddCommand : execute() +activate AddCommand + +AddCommand -> Model : addContact(contact) +activate Model + +Model --> AddCommand +deactivate Model + +create CommandResult +AddCommand -> CommandResult +activate CommandResult + +CommandResult --> AddCommand +deactivate CommandResult + +AddCommand --> LogicManager : result +deactivate AddCommand + +[<--LogicManager +deactivate LogicManager + +@enduml diff --git a/docs/diagrams/ArchitectureSequenceDiagram.puml b/docs/diagrams/ArchitectureSequenceDiagram.puml index 48b6cc4333c..23d0e289600 100644 --- a/docs/diagrams/ArchitectureSequenceDiagram.puml +++ b/docs/diagrams/ArchitectureSequenceDiagram.puml @@ -14,13 +14,13 @@ activate ui UI_COLOR ui -[UI_COLOR]> logic : execute("delete 1") activate logic LOGIC_COLOR -logic -[LOGIC_COLOR]> model : deletePerson(p) +logic -[LOGIC_COLOR]> model : removeContact(p) activate model MODEL_COLOR model -[MODEL_COLOR]-> logic deactivate model -logic -[LOGIC_COLOR]> storage : saveAddressBook(addressBook) +logic -[LOGIC_COLOR]> storage : saveContacts(contacts) activate storage STORAGE_COLOR storage -[STORAGE_COLOR]> storage : Save to file diff --git a/docs/diagrams/BetterModelClassDiagram.puml b/docs/diagrams/BetterModelClassDiagram.puml deleted file mode 100644 index 598474a5c82..00000000000 --- a/docs/diagrams/BetterModelClassDiagram.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam arrowThickness 1.1 -skinparam arrowColor MODEL_COLOR -skinparam classBackgroundColor MODEL_COLOR - -AddressBook *-right-> "1" UniquePersonList -AddressBook *-right-> "1" UniqueTagList -UniqueTagList -[hidden]down- UniquePersonList -UniqueTagList -[hidden]down- UniquePersonList - -UniqueTagList -right-> "*" Tag -UniquePersonList -right-> Person - -Person -up-> "*" Tag - -Person *--> Name -Person *--> Phone -Person *--> Email -Person *--> Address -@enduml diff --git a/docs/diagrams/CommandBoxHistoryNewSequenceDiagram.puml b/docs/diagrams/CommandBoxHistoryNewSequenceDiagram.puml new file mode 100644 index 00000000000..8e9d17b49c4 --- /dev/null +++ b/docs/diagrams/CommandBoxHistoryNewSequenceDiagram.puml @@ -0,0 +1,30 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Ui UI_COLOR_T1 +participant ":CommandBox" as CommandBox UI_COLOR +participant ":CommandExecutor" as CommandExecutor UI_COLOR +participant ":CommandBoxHistory" as CommandBoxHistory UI_COLOR +end box + +create CommandBox +[-> CommandBox : handleCommandEntered() + +CommandBox -> CommandExecutor : execute(commandText) +activate CommandExecutor + +CommandExecutor --> CommandBox +deactivate CommandExecutor + +CommandBox -> CommandBoxHistory : add(commandText) +activate CommandBoxHistory +CommandBoxHistory --> CommandBox +deactivate CommandBoxHistory + +CommandBox -> CommandBoxHistory : resetPointer() +activate CommandBoxHistory +CommandBoxHistory --> CommandBox +deactivate CommandBoxHistory + +@enduml diff --git a/docs/diagrams/CommandBoxHistorySequenceDiagram.puml b/docs/diagrams/CommandBoxHistorySequenceDiagram.puml new file mode 100644 index 00000000000..50335fb709e --- /dev/null +++ b/docs/diagrams/CommandBoxHistorySequenceDiagram.puml @@ -0,0 +1,29 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Ui UI_COLOR_T1 +participant ":CommandBox" as CommandBox UI_COLOR +participant ":CommandBoxHistory" as CommandBoxHistory UI_COLOR +end box + +create CommandBox +[-> CommandBox : handleKeyPress(UP) + +CommandBox -> CommandBox :switchToPreviousCommand() +activate CommandBox + +CommandBox -> CommandBoxHistory : previous() +activate CommandBoxHistory +CommandBoxHistory --> CommandBox : previousCommand +deactivate CommandBoxHistory + +CommandBox -> CommandBox : replaceText(previousCommand) +activate CommandBox +CommandBox --> CommandBox +deactivate CommandBox + +CommandBox --> CommandBox +deactivate CommandBox + +@enduml diff --git a/docs/diagrams/DeleteSequenceDiagram.puml b/docs/diagrams/DeleteSequenceDiagram.puml index 40ea6c9dc4c..ec1bc45de82 100644 --- a/docs/diagrams/DeleteSequenceDiagram.puml +++ b/docs/diagrams/DeleteSequenceDiagram.puml @@ -4,7 +4,7 @@ skinparam ArrowFontStyle plain box Logic LOGIC_COLOR_T1 participant ":LogicManager" as LogicManager LOGIC_COLOR -participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR +participant ":InputParser" as InputParser LOGIC_COLOR participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR participant "d:DeleteCommand" as DeleteCommand LOGIC_COLOR participant ":CommandResult" as CommandResult LOGIC_COLOR @@ -14,20 +14,20 @@ box Model MODEL_COLOR_T1 participant ":Model" as Model MODEL_COLOR end box -[-> LogicManager : execute("delete 1") +[-> LogicManager : execute("delete 1 3 5") activate LogicManager -LogicManager -> AddressBookParser : parseCommand("delete 1") -activate AddressBookParser +LogicManager -> InputParser : parseCommand("delete 1 3 5") +activate InputParser create DeleteCommandParser -AddressBookParser -> DeleteCommandParser +InputParser -> DeleteCommandParser activate DeleteCommandParser -DeleteCommandParser --> AddressBookParser +DeleteCommandParser --> InputParser deactivate DeleteCommandParser -AddressBookParser -> DeleteCommandParser : parse("1") +InputParser -> DeleteCommandParser : parse("1 3 5") activate DeleteCommandParser create DeleteCommand @@ -37,24 +37,27 @@ activate DeleteCommand DeleteCommand --> DeleteCommandParser : d deactivate DeleteCommand -DeleteCommandParser --> AddressBookParser : d +DeleteCommandParser --> InputParser : d deactivate DeleteCommandParser -'Hidden arrow to position the destroy marker below the end of the activation bar. -DeleteCommandParser -[hidden]-> AddressBookParser -destroy DeleteCommandParser -AddressBookParser --> LogicManager : d -deactivate AddressBookParser +InputParser --> LogicManager : d +deactivate InputParser LogicManager -> DeleteCommand : execute() activate DeleteCommand -DeleteCommand -> Model : deletePerson(1) +DeleteCommand -> Model : getFilteredContactList() activate Model - -Model --> DeleteCommand +Model --> DeleteCommand : currentContactList deactivate Model +loop for each contact in contactsToDelete + DeleteCommand -> Model : removeContact(contact) + activate Model + Model --> DeleteCommand + deactivate Model +end + create CommandResult DeleteCommand -> CommandResult activate CommandResult @@ -67,4 +70,5 @@ deactivate DeleteCommand [<--LogicManager deactivate LogicManager +deactivate CommandResult @enduml diff --git a/docs/diagrams/EditActivityDiagram.puml b/docs/diagrams/EditActivityDiagram.puml new file mode 100644 index 00000000000..4e0625874da --- /dev/null +++ b/docs/diagrams/EditActivityDiagram.puml @@ -0,0 +1,18 @@ +@startuml +skin rose +skinparam ActivityFontSize 15 +skinparam ArrowFontSize 12 +start +:User executes command; + +:New Contact object is created; + +'Since the beta syntax does not support placing the condition outside the +'diamond we place it as the true branch instead. +if () then ([new Contact is not duplicate]) + :Replace existing Contact with new Contact + in UniqueContactList; +else ([else]) +endif +stop +@enduml diff --git a/docs/diagrams/EditSequenceDiagram.puml b/docs/diagrams/EditSequenceDiagram.puml new file mode 100644 index 00000000000..e838536c8e0 --- /dev/null +++ b/docs/diagrams/EditSequenceDiagram.puml @@ -0,0 +1,78 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":InputParser" as InputParser LOGIC_COLOR +participant ":AddCommandParser" as AddCommandParser LOGIC_COLOR +participant "a:AddCommand" as AddCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +participant "contact:Contact" as Contact MODEL_COLOR +end box + +[-> LogicManager : execute("add n/Alice ...") +activate LogicManager + +LogicManager -> InputParser : parseCommand("add n/Alice ...") +activate InputParser + +create AddCommandParser +InputParser -> AddCommandParser +activate AddCommandParser + +AddCommandParser --> InputParser +deactivate AddCommandParser + +InputParser -> AddCommandParser : parse("n/Alice ...") +activate AddCommandParser + + + +create Contact +AddCommandParser -> Contact +activate Contact + +Contact --> AddCommandParser : contact +deactivate Contact + +create AddCommand +AddCommandParser -> AddCommand +activate AddCommand + +AddCommand --> AddCommandParser : a +deactivate AddCommand + +AddCommandParser --> InputParser : a +deactivate AddCommandParser + +InputParser --> LogicManager : a +deactivate InputParser + +LogicManager -> AddCommand : execute() +activate AddCommand + +AddCommand -> Model : addContact(contact) +activate Model + +Model --> AddCommand +deactivate Model + +create CommandResult +AddCommand -> CommandResult +activate CommandResult + +CommandResult --> AddCommand +deactivate CommandResult + +AddCommand --> LogicManager : result +deactivate AddCommand + +[<--LogicManager +deactivate LogicManager + +@enduml diff --git a/docs/diagrams/FilterSequenceDiagram.puml b/docs/diagrams/FilterSequenceDiagram.puml new file mode 100644 index 00000000000..b48a218a9ae --- /dev/null +++ b/docs/diagrams/FilterSequenceDiagram.puml @@ -0,0 +1,35 @@ +@startuml +!include style.puml +skinparam ArrowFontStyle plain + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":FilterCommand" as FilterCommand LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant "model:Model" as Model MODEL_COLOR +end box + +[-> LogicManager : execute("filter Friend") + +create FilterCommand +LogicManager -> FilterCommand : +activate FilterCommand +FilterCommand --> LogicManager +deactivate FilterCommand + + +LogicManager -> FilterCommand : execute(model) +activate FilterCommand + + +FilterCommand -> Model : setContactsFilter(predicate) +activate Model +Model --> FilterCommand +deactivate Model + +FilterCommand --> LogicManager +deactivate FilterCommand + +@enduml diff --git a/docs/diagrams/LogicClassDiagram.puml b/docs/diagrams/LogicClassDiagram.puml index a57720890ee..6b34880d4ad 100644 --- a/docs/diagrams/LogicClassDiagram.puml +++ b/docs/diagrams/LogicClassDiagram.puml @@ -6,7 +6,7 @@ skinparam classBackgroundColor LOGIC_COLOR package Logic as LogicPackage { -Class AddressBookParser +Class InputParser Class XYZCommand Class CommandResult Class "{abstract}\nCommand" as Command @@ -27,8 +27,8 @@ Class HiddenOutside #FFFFFF HiddenOutside ..> Logic LogicManager .right.|> Logic -LogicManager -right->"1" AddressBookParser -AddressBookParser ..> XYZCommand : creates > +LogicManager -right->"1" InputParser +InputParser ..> XYZCommand : creates > XYZCommand -up-|> Command LogicManager .left.> Command : executes > diff --git a/docs/diagrams/ModelClassDiagram.puml b/docs/diagrams/ModelClassDiagram.puml index 0de5673070d..30beb54270b 100644 --- a/docs/diagrams/ModelClassDiagram.puml +++ b/docs/diagrams/ModelClassDiagram.puml @@ -5,20 +5,21 @@ skinparam arrowColor MODEL_COLOR skinparam classBackgroundColor MODEL_COLOR Package Model as ModelPackage <>{ -Class "<>\nReadOnlyAddressBook" as ReadOnlyAddressBook -Class "<>\nReadOnlyUserPrefs" as ReadOnlyUserPrefs +Class "<>\nReadOnlyContacts" as ReadOnlyContacts +Class "<>\nReadOnlySettings" as ReadOnlySettings Class "<>\nModel" as Model -Class AddressBook +Class Contacts Class ModelManager -Class UserPrefs +Class Settings -Class UniquePersonList -Class Person -Class Address +Class UniqueContactList +Class Contact +Class Note Class Email Class Name Class Phone Class Tag +Class AlternateContact Class I #FFFFFF } @@ -26,29 +27,30 @@ Class I #FFFFFF Class HiddenOutside #FFFFFF HiddenOutside ..> Model -AddressBook .up.|> ReadOnlyAddressBook +Contacts .up.|> ReadOnlyContacts ModelManager .up.|> Model -Model .right.> ReadOnlyUserPrefs -Model .left.> ReadOnlyAddressBook -ModelManager -left-> "1" AddressBook -ModelManager -right-> "1" UserPrefs -UserPrefs .up.|> ReadOnlyUserPrefs - -AddressBook *--> "1" UniquePersonList -UniquePersonList --> "~* all" Person -Person *--> Name -Person *--> Phone -Person *--> Email -Person *--> Address -Person *--> "*" Tag - -Person -[hidden]up--> I -UniquePersonList -[hidden]right-> I +Model .right.> ReadOnlySettings +Model .left.> ReadOnlyContacts +ModelManager -left-> "1" Contacts +ModelManager -right-> "1" Settings +Settings .up.|> ReadOnlySettings + +Contacts *--> "1" UniqueContactList +UniqueContactList --> "~* all" Contact +Contact *--> "1" Name +Contact *--> "1" Phone +Contact *--> "1" Email +Contact *--> "1" Note +Contact *--> "*" Tag +Contact *--> "*" AlternateContact + +Contact -[hidden]up--> I +UniqueContactList -[hidden]right-> I Name -[hidden]right-> Phone -Phone -[hidden]right-> Address -Address -[hidden]right-> Email +Phone -[hidden]right-> Email +Email -[hidden]right-> Note -ModelManager --> "~* filtered" Person +ModelManager --> "~* filtered" Contact @enduml diff --git a/docs/diagrams/ParserClasses.puml b/docs/diagrams/ParserClasses.puml index 0c7424de6e0..7e18f7bfc91 100644 --- a/docs/diagrams/ParserClasses.puml +++ b/docs/diagrams/ParserClasses.puml @@ -9,7 +9,7 @@ Class XYZCommand package "Parser classes"{ Class "<>\nParser" as Parser -Class AddressBookParser +Class InputParser Class XYZCommandParser Class CliSyntax Class ParserUtil @@ -19,12 +19,12 @@ Class Prefix } Class HiddenOutside #FFFFFF -HiddenOutside ..> AddressBookParser +HiddenOutside ..> InputParser -AddressBookParser .down.> XYZCommandParser: creates > +InputParser .down.> XYZCommandParser: creates > XYZCommandParser ..> XYZCommand : creates > -AddressBookParser ..> Command : returns > +InputParser ..> Command : returns > XYZCommandParser .up.|> Parser XYZCommandParser ..> ArgumentMultimap XYZCommandParser ..> ArgumentTokenizer diff --git a/docs/diagrams/StorageClassDiagram.puml b/docs/diagrams/StorageClassDiagram.puml index a821e06458c..33135549b39 100644 --- a/docs/diagrams/StorageClassDiagram.puml +++ b/docs/diagrams/StorageClassDiagram.puml @@ -6,20 +6,20 @@ skinparam classBackgroundColor STORAGE_COLOR package Storage as StoragePackage { -package "UserPrefs Storage" #F4F6F6{ -Class "<>\nUserPrefsStorage" as UserPrefsStorage -Class JsonUserPrefsStorage +package "Settings Storage" #F4F6F6{ +Class "<>\nSettingsStorage" as SettingsStorage +Class JsonSettingsStorage } Class "<>\nStorage" as Storage Class StorageManager -package "AddressBook Storage" #F4F6F6{ -Class "<>\nAddressBookStorage" as AddressBookStorage -Class JsonAddressBookStorage -Class JsonSerializableAddressBook -Class JsonAdaptedPerson -Class JsonAdaptedTag +package "ConText Storage" #F4F6F6{ +Class "<>\nContactsStorage" as ContactsStorage +Class JsonContactsStorage +Class JsonContacts +Class JsonContact +Class JsonTag } } @@ -28,16 +28,16 @@ Class HiddenOutside #FFFFFF HiddenOutside ..> Storage StorageManager .up.|> Storage -StorageManager -up-> "1" UserPrefsStorage -StorageManager -up-> "1" AddressBookStorage +StorageManager -up-> "1" SettingsStorage +StorageManager -up-> "1" ContactsStorage -Storage -left-|> UserPrefsStorage -Storage -right-|> AddressBookStorage +Storage -left-|> SettingsStorage +Storage -right-|> ContactsStorage -JsonUserPrefsStorage .up.|> UserPrefsStorage -JsonAddressBookStorage .up.|> AddressBookStorage -JsonAddressBookStorage ..> JsonSerializableAddressBook -JsonSerializableAddressBook --> "*" JsonAdaptedPerson -JsonAdaptedPerson --> "*" JsonAdaptedTag +JsonSettingsStorage .up.|> SettingsStorage +JsonContactsStorage .up.|> ContactsStorage +JsonContactsStorage ..> JsonContacts +JsonContacts --> "*" JsonContact +JsonContact --> "*" JsonTag @enduml diff --git a/docs/diagrams/UiClassDiagram.puml b/docs/diagrams/UiClassDiagram.puml index 95473d5aa19..7f0355f56f7 100644 --- a/docs/diagrams/UiClassDiagram.puml +++ b/docs/diagrams/UiClassDiagram.puml @@ -11,10 +11,11 @@ Class UiManager Class MainWindow Class HelpWindow Class ResultDisplay -Class PersonListPanel -Class PersonCard +Class ContactListPanel +Class ContactCard Class StatusBarFooter Class CommandBox +Class CommandBoxHistory } package Model <> { @@ -32,26 +33,28 @@ UiManager .left.|> Ui UiManager -down-> "1" MainWindow MainWindow *-down-> "1" CommandBox MainWindow *-down-> "1" ResultDisplay -MainWindow *-down-> "1" PersonListPanel +MainWindow *-down-> "1" ContactListPanel MainWindow *-down-> "1" StatusBarFooter MainWindow --> "0..1" HelpWindow -PersonListPanel -down-> "*" PersonCard +CommandBox --> "1" CommandBoxHistory + +ContactListPanel -down-> "*" ContactCard MainWindow -left-|> UiPart ResultDisplay --|> UiPart CommandBox --|> UiPart -PersonListPanel --|> UiPart -PersonCard --|> UiPart +ContactListPanel --|> UiPart +ContactCard --|> UiPart StatusBarFooter --|> UiPart HelpWindow --|> UiPart -PersonCard ..> Model +ContactCard ..> Model UiManager -right-> Logic MainWindow -left-> Logic -PersonListPanel -[hidden]left- HelpWindow +ContactListPanel -[hidden]left- HelpWindow HelpWindow -[hidden]left- CommandBox CommandBox -[hidden]left- ResultDisplay ResultDisplay -[hidden]left- StatusBarFooter diff --git a/docs/diagrams/UiMockup.pptx b/docs/diagrams/UiMockup.pptx new file mode 100644 index 00000000000..58075fff238 Binary files /dev/null and b/docs/diagrams/UiMockup.pptx differ diff --git a/docs/diagrams/UndoRedoState0.puml b/docs/diagrams/UndoRedoState0.puml deleted file mode 100644 index 43a45903ac9..00000000000 --- a/docs/diagrams/UndoRedoState0.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title Initial state - -package States { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab2:AddressBook" -} -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 -hide State2 -hide State3 - -class Pointer as "Current State" #FFFFFF -Pointer -up-> State1 -@end diff --git a/docs/diagrams/UndoRedoState1.puml b/docs/diagrams/UndoRedoState1.puml deleted file mode 100644 index 5a41e9e1651..00000000000 --- a/docs/diagrams/UndoRedoState1.puml +++ /dev/null @@ -1,23 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title After command "delete 5" - -package States <> { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab2:AddressBook" -} - -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 - -hide State3 - -class Pointer as "Current State" #FFFFFF - -Pointer -up-> State2 -@end diff --git a/docs/diagrams/UndoRedoState2.puml b/docs/diagrams/UndoRedoState2.puml deleted file mode 100644 index ad32fce1b0b..00000000000 --- a/docs/diagrams/UndoRedoState2.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title After command "add n/David" - -package States <> { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab2:AddressBook" -} - -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 - -class Pointer as "Current State" #FFFFFF - -Pointer -up-> State3 -@end diff --git a/docs/diagrams/UndoRedoState3.puml b/docs/diagrams/UndoRedoState3.puml deleted file mode 100644 index 9187a690036..00000000000 --- a/docs/diagrams/UndoRedoState3.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title After command "undo" - -package States <> { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab2:AddressBook" -} - -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 - -class Pointer as "Current State" #FFFFFF - -Pointer -up-> State2 -@end diff --git a/docs/diagrams/UndoRedoState4.puml b/docs/diagrams/UndoRedoState4.puml deleted file mode 100644 index 2bc631ffcd0..00000000000 --- a/docs/diagrams/UndoRedoState4.puml +++ /dev/null @@ -1,21 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title After command "list" - -package States <> { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab2:AddressBook" -} - -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 - -class Pointer as "Current State" #FFFFFF - -Pointer -up-> State2 -@end diff --git a/docs/diagrams/UndoRedoState5.puml b/docs/diagrams/UndoRedoState5.puml deleted file mode 100644 index e77b04104aa..00000000000 --- a/docs/diagrams/UndoRedoState5.puml +++ /dev/null @@ -1,22 +0,0 @@ -@startuml -!include style.puml -skinparam ClassFontColor #000000 -skinparam ClassBorderColor #000000 -skinparam ClassBackgroundColor #FFFFAA - -title After command "clear" - -package States <> { - class State1 as "ab0:AddressBook" - class State2 as "ab1:AddressBook" - class State3 as "ab3:AddressBook" -} - -State1 -[hidden]right-> State2 -State2 -[hidden]right-> State3 - -class Pointer as "Current State" #FFFFFF - -Pointer -up-> State3 -note right on link: State ab2 deleted. -@end diff --git a/docs/diagrams/UndoSequenceDiagram.puml b/docs/diagrams/UndoSequenceDiagram.puml deleted file mode 100644 index 87ff3e9237e..00000000000 --- a/docs/diagrams/UndoSequenceDiagram.puml +++ /dev/null @@ -1,54 +0,0 @@ -@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 "u:UndoCommand" as UndoCommand LOGIC_COLOR -end box - -box Model MODEL_COLOR_T1 -participant ":Model" as Model MODEL_COLOR -participant ":VersionedAddressBook" as VersionedAddressBook MODEL_COLOR -end box -[-> LogicManager : execute(undo) -activate LogicManager - -LogicManager -> AddressBookParser : parseCommand(undo) -activate AddressBookParser - -create UndoCommand -AddressBookParser -> UndoCommand -activate UndoCommand - -UndoCommand --> AddressBookParser -deactivate UndoCommand - -AddressBookParser --> LogicManager : u -deactivate AddressBookParser - -LogicManager -> UndoCommand : execute() -activate UndoCommand - -UndoCommand -> Model : undoAddressBook() -activate Model - -Model -> VersionedAddressBook : undo() -activate VersionedAddressBook - -VersionedAddressBook -> VersionedAddressBook :resetData(ReadOnlyAddressBook) -VersionedAddressBook --> Model : -deactivate VersionedAddressBook - -Model --> UndoCommand -deactivate Model - -UndoCommand --> LogicManager : result -deactivate UndoCommand -UndoCommand -[hidden]-> LogicManager : result -destroy UndoCommand - -[<--LogicManager -deactivate LogicManager -@enduml diff --git a/docs/diagrams/add-remark/ParserClass.puml b/docs/diagrams/add-remark/ParserClass.puml deleted file mode 100644 index 24d390a4023..00000000000 --- a/docs/diagrams/add-remark/ParserClass.puml +++ /dev/null @@ -1,14 +0,0 @@ -@startuml -hide circle -skinparam classAttributeIconSize 0 - -Class "<>\nParser" as Parser -Class RemarkCommandParser { - +parse(): RemarkCommand -} -Class ParserException - -RemarkCommandParser .up.|> Parser -Parser .right.> ParserException: throws > -RemarkCommandParser .right.> ParserException: throws > -@enduml diff --git a/docs/diagrams/add-remark/RemarkClass.puml b/docs/diagrams/add-remark/RemarkClass.puml deleted file mode 100644 index 019c1ecbbf1..00000000000 --- a/docs/diagrams/add-remark/RemarkClass.puml +++ /dev/null @@ -1,19 +0,0 @@ -@startuml -hide circle -skinparam classAttributeIconSize 0 - -Class "{abstract}\nCommand" as Command { - +execute(Model): CommandResult -} -Class RemarkCommand { - +COMMAND_WORD: String - +MESSAGE_USAGE: String - +MESSAGE_NOT_IMPLEMENTED_YET: String - +execute(Model): CommandResult -} -Class CommandException - -RemarkCommand -up-|> Command -Command ..> CommandException: throws > -RemarkCommand .right.> CommandException: throws > -@enduml diff --git a/docs/diagrams/tracing/LogicSequenceDiagram.puml b/docs/diagrams/tracing/LogicSequenceDiagram.puml deleted file mode 100644 index 42bf46d3ce8..00000000000 --- a/docs/diagrams/tracing/LogicSequenceDiagram.puml +++ /dev/null @@ -1,22 +0,0 @@ -@startuml -!include ../style.puml -skinparam ArrowFontStyle plain - -Participant ":LogicManager" as logic LOGIC_COLOR -Participant ":AddressBookParser" as abp LOGIC_COLOR -Participant ":EditCommandParser" as ecp LOGIC_COLOR -Participant "command:EditCommand" as ec LOGIC_COLOR - -[-> logic : execute -activate logic -logic -> abp ++: parseCommand(commandText) -create ecp -abp -> ecp -abp -> ecp ++: parse(arguments) -create ec -ecp -> ec ++: index, editPersonDescriptor -ec --> ecp -- -ecp --> abp --: command -abp --> logic --: command - -@enduml diff --git a/docs/images/AddActivityDiagram.png b/docs/images/AddActivityDiagram.png new file mode 100644 index 00000000000..4192edc4a19 Binary files /dev/null and b/docs/images/AddActivityDiagram.png differ diff --git a/docs/images/AddSequenceDiagram.png b/docs/images/AddSequenceDiagram.png new file mode 100644 index 00000000000..9d130251f89 Binary files /dev/null and b/docs/images/AddSequenceDiagram.png differ diff --git a/docs/images/ArchitectureSequenceDiagram.png b/docs/images/ArchitectureSequenceDiagram.png index 37ad06a2803..9e4264e1180 100644 Binary files a/docs/images/ArchitectureSequenceDiagram.png and b/docs/images/ArchitectureSequenceDiagram.png differ diff --git a/docs/images/BetterModelClassDiagram.png b/docs/images/BetterModelClassDiagram.png deleted file mode 100644 index 02a42e35e76..00000000000 Binary files a/docs/images/BetterModelClassDiagram.png and /dev/null differ diff --git a/docs/images/CommandBoxHistoryNewSequenceDiagram.png b/docs/images/CommandBoxHistoryNewSequenceDiagram.png new file mode 100644 index 00000000000..918ba818718 Binary files /dev/null and b/docs/images/CommandBoxHistoryNewSequenceDiagram.png differ diff --git a/docs/images/CommandBoxHistorySequenceDiagram.png b/docs/images/CommandBoxHistorySequenceDiagram.png new file mode 100644 index 00000000000..a3b448055eb Binary files /dev/null and b/docs/images/CommandBoxHistorySequenceDiagram.png differ diff --git a/docs/images/CommitActivityDiagram.png b/docs/images/CommitActivityDiagram.png deleted file mode 100644 index 5b464126b35..00000000000 Binary files a/docs/images/CommitActivityDiagram.png and /dev/null differ diff --git a/docs/images/ComponentManagers.png b/docs/images/ComponentManagers.png index ae52a35718a..96ed098e500 100644 Binary files a/docs/images/ComponentManagers.png and b/docs/images/ComponentManagers.png differ diff --git a/docs/images/ContactCard.png b/docs/images/ContactCard.png new file mode 100644 index 00000000000..ab6bed45212 Binary files /dev/null and b/docs/images/ContactCard.png differ diff --git a/docs/images/DeleteSequenceDiagram.png b/docs/images/DeleteSequenceDiagram.png index e186f7ba096..19da5bc8642 100644 Binary files a/docs/images/DeleteSequenceDiagram.png and b/docs/images/DeleteSequenceDiagram.png differ diff --git a/docs/images/EditActivityDiagram.png b/docs/images/EditActivityDiagram.png new file mode 100644 index 00000000000..1eb618cf5d5 Binary files /dev/null and b/docs/images/EditActivityDiagram.png differ diff --git a/docs/images/EditSequenceDiagram.png b/docs/images/EditSequenceDiagram.png new file mode 100644 index 00000000000..9d130251f89 Binary files /dev/null and b/docs/images/EditSequenceDiagram.png differ diff --git a/docs/images/FilterSequenceDiagram.png b/docs/images/FilterSequenceDiagram.png new file mode 100644 index 00000000000..d5988eee4ba Binary files /dev/null and b/docs/images/FilterSequenceDiagram.png differ diff --git a/docs/images/LogicClassDiagram.png b/docs/images/LogicClassDiagram.png index e3b784310fe..24f7aca60a9 100644 Binary files a/docs/images/LogicClassDiagram.png and b/docs/images/LogicClassDiagram.png differ diff --git a/docs/images/LogicSequenceDiagram.png b/docs/images/LogicSequenceDiagram.png new file mode 100644 index 00000000000..9ba3f76d1b1 Binary files /dev/null and b/docs/images/LogicSequenceDiagram.png differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png index a19fb1b4ac8..c2cd37ff867 100644 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/ParserClasses.png b/docs/images/ParserClasses.png index edfd1ff7897..720c5caafcb 100644 Binary files a/docs/images/ParserClasses.png and b/docs/images/ParserClasses.png differ diff --git a/docs/images/SeEduLogo.png b/docs/images/SeEduLogo.png deleted file mode 100644 index 31ad50b6f88..00000000000 Binary files a/docs/images/SeEduLogo.png and /dev/null differ diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png index 18fa4d0d51f..f4f97a2f51d 100644 Binary files a/docs/images/StorageClassDiagram.png and b/docs/images/StorageClassDiagram.png differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2..23d8e203243 100644 Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png index 11f06d68671..af80e581b72 100644 Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/UndoRedoState0.png b/docs/images/UndoRedoState0.png deleted file mode 100644 index c5f91b58533..00000000000 Binary files a/docs/images/UndoRedoState0.png and /dev/null differ diff --git a/docs/images/UndoRedoState1.png b/docs/images/UndoRedoState1.png deleted file mode 100644 index 2d3ad09c047..00000000000 Binary files a/docs/images/UndoRedoState1.png and /dev/null differ diff --git a/docs/images/UndoRedoState2.png b/docs/images/UndoRedoState2.png deleted file mode 100644 index 20853694e03..00000000000 Binary files a/docs/images/UndoRedoState2.png and /dev/null differ diff --git a/docs/images/UndoRedoState3.png b/docs/images/UndoRedoState3.png deleted file mode 100644 index 1a9551b31be..00000000000 Binary files a/docs/images/UndoRedoState3.png and /dev/null differ diff --git a/docs/images/UndoRedoState4.png b/docs/images/UndoRedoState4.png deleted file mode 100644 index 46dfae78c94..00000000000 Binary files a/docs/images/UndoRedoState4.png and /dev/null differ diff --git a/docs/images/UndoRedoState5.png b/docs/images/UndoRedoState5.png deleted file mode 100644 index f45889b5fdf..00000000000 Binary files a/docs/images/UndoRedoState5.png and /dev/null differ diff --git a/docs/images/UndoSequenceDiagram.png b/docs/images/UndoSequenceDiagram.png deleted file mode 100644 index c7a7e637266..00000000000 Binary files a/docs/images/UndoSequenceDiagram.png and /dev/null differ diff --git a/docs/images/add-remark/$Remark.png b/docs/images/add-remark/$Remark.png deleted file mode 100644 index 959c634406d..00000000000 Binary files a/docs/images/add-remark/$Remark.png and /dev/null differ diff --git a/docs/images/add-remark/ContextMenu.png b/docs/images/add-remark/ContextMenu.png deleted file mode 100644 index 77536724e45..00000000000 Binary files a/docs/images/add-remark/ContextMenu.png and /dev/null differ diff --git a/docs/images/add-remark/CreateTest.png b/docs/images/add-remark/CreateTest.png deleted file mode 100644 index 6b7d6dcafec..00000000000 Binary files a/docs/images/add-remark/CreateTest.png and /dev/null differ diff --git a/docs/images/add-remark/GradleRun.png b/docs/images/add-remark/GradleRun.png deleted file mode 100644 index 281cc45f098..00000000000 Binary files a/docs/images/add-remark/GradleRun.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkBound.png b/docs/images/add-remark/RemarkBound.png deleted file mode 100644 index d335382b286..00000000000 Binary files a/docs/images/add-remark/RemarkBound.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkCommandClass.png b/docs/images/add-remark/RemarkCommandClass.png deleted file mode 100644 index 5687a3e9585..00000000000 Binary files a/docs/images/add-remark/RemarkCommandClass.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkCommandParserClass.png b/docs/images/add-remark/RemarkCommandParserClass.png deleted file mode 100644 index d5ad9c8a02f..00000000000 Binary files a/docs/images/add-remark/RemarkCommandParserClass.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkComplete.png b/docs/images/add-remark/RemarkComplete.png deleted file mode 100644 index 124ced2c752..00000000000 Binary files a/docs/images/add-remark/RemarkComplete.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkFailureOutput.png b/docs/images/add-remark/RemarkFailureOutput.png deleted file mode 100644 index 351257ea332..00000000000 Binary files a/docs/images/add-remark/RemarkFailureOutput.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkHello.png b/docs/images/add-remark/RemarkHello.png deleted file mode 100644 index aad48d02f8f..00000000000 Binary files a/docs/images/add-remark/RemarkHello.png and /dev/null differ diff --git a/docs/images/add-remark/RemarkNotImplemented.png b/docs/images/add-remark/RemarkNotImplemented.png deleted file mode 100644 index 1d187f39403..00000000000 Binary files a/docs/images/add-remark/RemarkNotImplemented.png and /dev/null differ diff --git a/docs/images/bwangpj.png b/docs/images/bwangpj.png new file mode 100644 index 00000000000..b7afc738c48 Binary files /dev/null and b/docs/images/bwangpj.png differ diff --git a/docs/images/cloud7050.png b/docs/images/cloud7050.png new file mode 100644 index 00000000000..ee6a0bfdfe1 Binary files /dev/null and b/docs/images/cloud7050.png differ diff --git a/docs/images/findAlexDavidResult.png b/docs/images/findAlexDavidResult.png deleted file mode 100644 index 235da1c273e..00000000000 Binary files a/docs/images/findAlexDavidResult.png and /dev/null differ diff --git a/docs/images/helpMessage.png b/docs/images/helpMessage.png deleted file mode 100644 index b1f70470137..00000000000 Binary files a/docs/images/helpMessage.png and /dev/null differ diff --git a/docs/images/johndoe.png b/docs/images/johndoe.png deleted file mode 100644 index 1ce7ce16dc8..00000000000 Binary files a/docs/images/johndoe.png and /dev/null differ diff --git a/docs/images/mamayuan.png b/docs/images/mamayuan.png new file mode 100644 index 00000000000..371e2972576 Binary files /dev/null and b/docs/images/mamayuan.png differ diff --git a/docs/images/rayshawntan.png b/docs/images/rayshawntan.png new file mode 100644 index 00000000000..0bf6df2b2f1 Binary files /dev/null and b/docs/images/rayshawntan.png differ diff --git a/docs/images/remove/$address.png b/docs/images/remove/$address.png deleted file mode 100644 index cf0434e0e83..00000000000 Binary files a/docs/images/remove/$address.png and /dev/null differ diff --git a/docs/images/remove/SafeDeleteConflicts.png b/docs/images/remove/SafeDeleteConflicts.png deleted file mode 100644 index 8f0abeffd4d..00000000000 Binary files a/docs/images/remove/SafeDeleteConflicts.png and /dev/null differ diff --git a/docs/images/remove/UnsafeDelete.png b/docs/images/remove/UnsafeDelete.png deleted file mode 100644 index 9e376d02a0c..00000000000 Binary files a/docs/images/remove/UnsafeDelete.png and /dev/null differ diff --git a/docs/images/remove/UnsafeDeleteOnField.png b/docs/images/remove/UnsafeDeleteOnField.png deleted file mode 100644 index 44d5bb0a442..00000000000 Binary files a/docs/images/remove/UnsafeDeleteOnField.png and /dev/null differ diff --git a/docs/images/request_access.png b/docs/images/request_access.png deleted file mode 100644 index 12e8a81bd28..00000000000 Binary files a/docs/images/request_access.png and /dev/null differ diff --git a/docs/images/tracing/DebuggerStep1.png b/docs/images/tracing/DebuggerStep1.png deleted file mode 100644 index 6d088ae63de..00000000000 Binary files a/docs/images/tracing/DebuggerStep1.png and /dev/null differ diff --git a/docs/images/tracing/EditCommand.png b/docs/images/tracing/EditCommand.png deleted file mode 100644 index ed34ad08b98..00000000000 Binary files a/docs/images/tracing/EditCommand.png and /dev/null differ diff --git a/docs/images/tracing/FindUsages.png b/docs/images/tracing/FindUsages.png deleted file mode 100644 index e074d0e86c9..00000000000 Binary files a/docs/images/tracing/FindUsages.png and /dev/null differ diff --git a/docs/images/tracing/LeftGutter.png b/docs/images/tracing/LeftGutter.png deleted file mode 100644 index 571acf99e7b..00000000000 Binary files a/docs/images/tracing/LeftGutter.png and /dev/null differ diff --git a/docs/images/tracing/LogicSequenceDiagram.png b/docs/images/tracing/LogicSequenceDiagram.png deleted file mode 100644 index 25c8b66b9f1..00000000000 Binary files a/docs/images/tracing/LogicSequenceDiagram.png and /dev/null differ diff --git a/docs/images/tracing/ShowExecutionPoint.png b/docs/images/tracing/ShowExecutionPoint.png deleted file mode 100644 index ea72176fa64..00000000000 Binary files a/docs/images/tracing/ShowExecutionPoint.png and /dev/null differ diff --git a/docs/images/tracing/StepInto.png b/docs/images/tracing/StepInto.png deleted file mode 100644 index ddfa0e2aeb8..00000000000 Binary files a/docs/images/tracing/StepInto.png and /dev/null differ diff --git a/docs/images/tracing/StepOver.png b/docs/images/tracing/StepOver.png deleted file mode 100644 index ed5fb276e29..00000000000 Binary files a/docs/images/tracing/StepOver.png and /dev/null differ diff --git a/docs/images/tracing/StructureToolWindow.png b/docs/images/tracing/StructureToolWindow.png deleted file mode 100644 index c377c331d5f..00000000000 Binary files a/docs/images/tracing/StructureToolWindow.png and /dev/null differ diff --git a/docs/images/tracing/Variables.png b/docs/images/tracing/Variables.png deleted file mode 100644 index 02ea7b15520..00000000000 Binary files a/docs/images/tracing/Variables.png and /dev/null differ diff --git a/docs/images/tracing/searchResultsForExecuteMethod.png b/docs/images/tracing/searchResultsForExecuteMethod.png deleted file mode 100644 index 845a0c94687..00000000000 Binary files a/docs/images/tracing/searchResultsForExecuteMethod.png and /dev/null differ diff --git a/docs/index.md b/docs/index.md index 7601dbaad0d..24df5531558 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,19 +1,15 @@ --- layout: page -title: AddressBook Level-3 +title: ConText --- -[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) -[![codecov](https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg)](https://codecov.io/gh/se-edu/addressbook-level3) +[![Java CI](https://github.com/AY2324S1-CS2103-W14-3/tp/actions/workflows/gradle.yml/badge.svg)](https://github.com/AY2324S1-CS2103-W14-3/tp/actions/workflows/gradle.yml) +[![codecov](https://codecov.io/gh/AY2324S1-CS2103-W14-3/tp/graph/badge.svg?token=KT7MNHKALX)](https://codecov.io/gh/AY2324S1-CS2103-W14-3/tp) -![Ui](images/Ui.png) +![UI](images/Ui.png) -**AddressBook is a desktop application for managing your contact details.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). +**ConText** is a desktop app that allows for managing contacts quickly via text commands, with useful features relevant to NUS SoC students. +While it has a Graphical User Interface, most of its user interactions happen via an in-app Command Line Interface. -* If you are interested in using AddressBook, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start). -* If you are interested about developing AddressBook, the [**Developer Guide**](DeveloperGuide.html) is a good place to start. - - -**Acknowledgements** - -* Libraries used: [JavaFX](https://openjfx.io/), [Jackson](https://github.com/FasterXML/jackson), [JUnit5](https://github.com/junit-team/junit5) +- If you are interested in using ConText, please check out the [**User Guide**](./UserGuide.html). +- If you are interested about developing ConText, the [**Developer Guide**](./DeveloperGuide.html) is a good place to start. diff --git a/docs/team/bwangpj.md b/docs/team/bwangpj.md new file mode 100644 index 00000000000..f49753c80a4 --- /dev/null +++ b/docs/team/bwangpj.md @@ -0,0 +1,62 @@ +--- +layout: page +title: Bryan's Project Portfolio Page +--- + + + + +## Overview + +**ConText** is a desktop app that allows for managing contacts quickly via text commands, with useful features relevant to NUS SoC students. +While it has a Graphical User Interface, most of its user interactions happen via an in-app Command Line Interface. + +## Summary of contributions + +### Code contributed + +[TP RepoSense Code Dashboard](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=bwangpj&breakdown=true) + +### Enhancements implemented + +1. Filter command to allow users to filter contacts by Tag, and associated tests +2. Store command history and allow navigating between previous commands using up/down arrow keys, similar to an actual CLI, and associated tests + +### Contributions to the UG + +- Describe useful features relevant to NUS SoC students at the start of the UG, i.e. filtering and navigating between commands using up/down arrow keys +- Include labelled UI diagram of the various information that is stored and displayed in the UI +- Include documentation for `filter` command +- Explain and emphasise that indexing is 1-based and not 0-based +- Explain and emphasise how duplicate contacts are handled - only by name, and only with an exact match of name +- Clarify how input commands with empty fields are handled + +### Contributions to the DG + +- Include initial list of all user stories brainstormed +- Describe implementation of: + - `edit` command + - `filter` command + - navigation between command history using up/down arrow keys; including the `UI` component as well as description of how the feature is implemented using `CommandBoxHistory` + + and their associated UML diagrams. +- Add Planned Enhancements appendix to the DG + +### Contributions to team-based tasks + +- Rename objects in the code to remove traces of AB3, and the associated big refactor +- Remove traces of AB3 from Jekyll +- Remove tutorials and images used in tutorials from the docs +- Release of v1.3 (trial) +- Triage and collate the PE-D bugs for Planned Enhancements +- Help with miscellaneous checkstyle corrections to pass checkstyle + +### Review/mentoring contributions + +- Review PRs to catch things that may have been missed. +E.g. https://github.com/AY2324S1-CS2103-W14-3/tp/pull/71#discussion_r1361430312 +- Contribute to discussions on GitHub, Telegram and Zoom. + +### Contributions beyond the project team + +- Put a good amount of effort into [finding bugs during the PE-D](https://github.com/AY2324S1-CS2103T-T17-4/tp/issues?q=is%3Aissue+c%5D). diff --git a/docs/team/cloud7050.md b/docs/team/cloud7050.md new file mode 100644 index 00000000000..5015a517bf3 --- /dev/null +++ b/docs/team/cloud7050.md @@ -0,0 +1,70 @@ +--- +layout: page +title: Cloud7050's Project Portfolio Page +--- + + + + + +### Overview + +**ConText** is a desktop app that allows for managing contacts quickly via text commands, with useful features relevant to NUS SoC students. +While it has a Graphical User Interface, most of its user interactions happen via an in-app Command Line Interface. + +### Code contributed + +[TP RepoSense Code Dashboard](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=cloud7050&breakdown=true) + +### Enhancements implemented + +- Notes feature with flexible validation, integrated with `add`, `edit`, UI, tests. +- Automatic sorting, integrated with `find`, `filter`. +- Designed & helped implement `TestData`, `Messages`. +- Helped with planning & doing wide-sweeping refactoring, including simplifications, code quality, test case improvements. Scrapped various overkill parts of AB3, e.g. `Version`. Helped clean dead/irrelevant files from AB3 (e.g. images, tutorials). +- Helped update many test cases to match our product. Improved existing tests (e.g. `@TempDir` instead of sandbox). Wrote new tests. +- Updated/enhanced/fixed various Javadocs. + +### Contributions to the UG + +- Wrote sections: Intro, quick start, command format, command details, sorting/saving, limitations. +- Merged AB3 UG back into draft UG. Full pass over UG to add/update/enhance contents. +- Proofread & fixed/filed issues after pages finished building, i.e. after PR reviews. + +### Contributions to the DG + + + + + + +- Wrote sections: Sorting, acknowledgements, product scope, NFRs. +- Added to sections: Enhancements. +- Helped update to match our product. +- Scrapped separate out-of-scope pages. + +### Contributions to team-based tasks + +- Set up: GitHub org, repo with labels/branch protections/user stories board, Jekyll, Codecov. +- Repo-wide refactor to match our product. +- Managed gradle configs, updated wrapper (e.g. dependencies, fix deprecation, simplification, `clean`). Relaxed checkstyle over time. Kept misc files like gitignore up to date. +- Defined most tasks in [issue tracker](https://github.com/AY2324S1-CS2103-W14-3/tp/issues?q=is%3Aissue+author%3ACloud7050), kept it updated & tidy. Managed milestones, labelled/tracked/edited/assigned tasks. Very active in [issue comments](https://nus-cs2103-ay2324s1.github.io/dashboards/contents/tp-comments.html#16-joel-leow-cloud7050-60-comments) (e.g. adding details/meeting notes). +- Helped perform milestone wrapups, releases. Performed week-specific tasks (e.g. triaging PE-D bugs, collating progress into MS Teams message). +- Tracked meeting agendas, tasks pending assignment/discussion. Made forum posts for clarifications. Tracked deliverables, ensured done before deadlines. Helped keep meetings moving, e.g. screenshare with annotations to facilitate discussions. +- Worked on docs sections not specific to anybody's features (e.g. [UG](#contributions-to-the-ug), [DG](#contributions-to-the-dg), README, `Ui.png`, `index.md`). +- Made PR template. Added reviewer assignment GitHub bot. + +### Review/mentoring contributions + +- Reviewed good portion of [team PRs](https://github.com/AY2324S1-CS2103-W14-3/tp/pulls?q=is%3Apr), [quite thoroughly](https://nus-cs2103-ay2324s1.github.io/dashboards/contents/tp-comments.html#16-joel-leow-cloud7050-60-comments) (spotlight: [#71](https://github.com/AY2324S1-CS2103-W14-3/tp/pull/71#issuecomment-1768352563)). Reviewed already merged PRs, opened various followup issues for things missed (e.g. [#53](https://github.com/AY2324S1-CS2103-W14-3/tp/issues/53), [#80](https://github.com/AY2324S1-CS2103-W14-3/tp/issues/80), [#122](https://github.com/AY2324S1-CS2103-W14-3/tp/issues/122)). +- Helped clarify/answer questions in GitHub/Telegram/Zoom discussions. Discussed steps for accomplishing certain tasks (e.g. git), ways to enhance certain aspects (e.g. regex). +- Pointed out notable things, e.g. [git details configured different from grading scripts](https://github.com/AY2324S1-CS2103-W14-3/tp/commits/master?after=7575f07d444894d96d1849ee81bbb0bdfcd05802+454&branch=master&qualified_name=refs%2Fheads%2Fmaster#:~:text=Remove%20rubbish-,DESKTOP%2DITF4GUD%5C94866,-committed%20on%20Oct), team repo watchers, [quiz part 1 automation](https://github.com/Cloud7050/js-canvastransfer). + +### Contributions beyond the project team + +- Put good effort into [finding HouR bugs during PE-D](https://github.com/AY2324S1-CS2103T-W12-1/tp/issues?q=is%3Aissue+c%5D). Checked on transferred issues in case I could help clarify. diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md deleted file mode 100644 index 773a07794e2..00000000000 --- a/docs/team/johndoe.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: page -title: John Doe's Project Portfolio Page ---- - -### Project: AddressBook Level 3 - -AddressBook - Level 3 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC. - -Given below are my contributions to the project. - -* **New Feature**: Added the ability to undo/redo previous commands. - * What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command. - * Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them. - * Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands. - * Credits: *{mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}* - -* **New Feature**: Added a history command that allows the user to navigate to previous commands using up/down keys. - -* **Code contributed**: [RepoSense link]() - -* **Project management**: - * Managed releases `v1.3` - `v1.5rc` (3 releases) on GitHub - -* **Enhancements to existing features**: - * Updated the GUI color scheme (Pull requests [\#33](), [\#34]()) - * Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests [\#36](), [\#38]()) - -* **Documentation**: - * User Guide: - * Added documentation for the features `delete` and `find` [\#72]() - * Did cosmetic tweaks to existing documentation of features `clear`, `exit`: [\#74]() - * Developer Guide: - * Added implementation details of the `delete` feature. - -* **Community**: - * PRs reviewed (with non-trivial review comments): [\#12](), [\#32](), [\#19](), [\#42]() - * Contributed to forum discussions (examples: [1](), [2](), [3](), [4]()) - * Reported bugs and suggestions for other teams in the class (examples: [1](), [2](), [3]()) - * Some parts of the history feature I added was adopted by several other class mates ([1](), [2]()) - -* **Tools**: - * Integrated a third party library (Natty) to the project ([\#42]()) - * Integrated a new Github plugin (CircleCI) to the team repo - -* _{you can add/remove categories in the list above}_ diff --git a/docs/team/mamayuan.md b/docs/team/mamayuan.md new file mode 100644 index 00000000000..870ed2ed5d8 --- /dev/null +++ b/docs/team/mamayuan.md @@ -0,0 +1,46 @@ +--- +layout: page +title: mamayuan's Project Portfolio Page +--- + +## Overview + +**ConText** is a desktop app that allows for managing contacts quickly via text commands, with useful features relevant to NUS SoC students. +While it has a Graphical User Interface, most of its user interactions happen via an in-app Command Line Interface. + +### Code contributed + +[TP RepoSense Code Dashboard](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=mamayuan&breakdown=true) + +### Enhancements implemented +- Enabled processing of multiple indices in the delete command. +- Developed a Messages.java class to ensure accurate message displays to users. +- Enhanced test files with updated test cases. + +### Contributions to the UG +- Initiated the User Guide setup. +- Addressed and corrected style and wording inconsistencies throughout the User Guide. +- Revised the section detailing the delete command. + +### Contributions to the DG +- Authored the Glossary and Manual Testing sections. +- Refinec `User Stories` section +- Specified implementation of `delete` command +- Updated the DeleteSequenceDiagram UML diagram to reflect new implementations and addressed potential bugs in other sequence diagrams. +- Fixed potential bugs for other sequence diagrams +- Edit `Appendix: Planned enhancements` +- Resolved naming inconsistencies inherited from AB3. + +### Contributions to team-based tasks +- Established a Messages.java class consolidating all user messages, previously dispersed across various files. +- Removed traces of AB3 in documentations and code +- Provided feedback for peer PRs +- Reminded team of deadlines +- Refactored code for better + +### Review/mentoring contributions +- Helped review some of [team PRs](https://github.com/AY2324S1-CS2103-W14-3/tp/pulls?q=is%3Apr) that required approval before merging into the master branch and provided relevant feedbacks. +- Contributed to GitHub/Telegram/Zoom discussions to help clarify/answer questions and add my thoughts. + +### Contributions beyond the project team +- During PE-D, I have put in extra effort to [find bugs](https://github.com/AY2324S1-CS2103T-T08-4/tp/issues) for the team assigned. diff --git a/docs/team/rayshawntan.md b/docs/team/rayshawntan.md new file mode 100644 index 00000000000..95b8384e47d --- /dev/null +++ b/docs/team/rayshawntan.md @@ -0,0 +1,46 @@ +--- +layout: page +title: rayshawntan's Project Portfolio Page +--- + +## Overview + +**ConText** is a desktop app that allows for managing contacts quickly via text commands. +It is optimized for use via an in-app Command Line Interface (CLI), while still having the benefits of a Graphical User Interface (GUI). + +## Summary of contributions + +### Code contributed + +My code contributions for this project can be seen here: [TP RepoSense Code Dashboard](https://nus-cs2103-ay2324s1.github.io/tp-dashboard/?search=rayshawntan&breakdown=false&sort=groupTitle%20dsc&sortWithin=title&since=2023-09-22&timeframe=commit&mergegroup=&groupSelect=groupByRepos) + +### Enhancements implemented + +* `AlternateContact` to allow users to store alternate means of contact. + +### Contributions to the UG + +* Update implementations of `add` and `edit` features +* Merge portions of AB3 UG back into our UG draft + +### Contributions to the DG + +* Include the list of use cases +* Describe implementation of `add` commands and the associated diagram + +### Contributions to team-based tasks + +* Add UI mockup of how we want our project to be initially +* Update the homepage of project to remove traces of AB3 +* Reorganise the test data used in test cases for easier locating of test data origin +* Remove traces of AB3 in documentations and code +* Release of v1.2b +* Demo of v1.2 and v1.3 + +### Review/mentoring contributions +* Review some of the [team PRs](https://github.com/AY2324S1-CS2103-W14-3/tp/pulls?q=is%3Apr) +* Examples of PRs reviewed with non-trivial comments: [\#112](https://github.com/AY2324S1-CS2103-W14-3/tp/pull/112), [\#197](https://github.com/AY2324S1-CS2103-W14-3/tp/pull/197) + +### Contributions beyond the project team +* During PE-D, I have put in effort to [find bugs](https://github.com/AY2324S1-CS2103T-T09-4/tp/issues?q=is%3Aissue+%22%5BPE-D%5D%5BTester+D%5D%22) that do not correspond to their UG + diff --git a/docs/tutorials/AddRemark.md b/docs/tutorials/AddRemark.md deleted file mode 100644 index d98f38982e7..00000000000 --- a/docs/tutorials/AddRemark.md +++ /dev/null @@ -1,399 +0,0 @@ ---- -layout: page -title: "Tutorial: Adding a command" ---- - -Let's walk you through the implementation of a new command — `remark`. - -This command allows users of the AddressBook application to add optional remarks to people in their address book and edit it if required. The command should have the following format: - -`remark INDEX r/REMARK` (e.g., `remark 2 r/Likes baseball`) - -We’ll assume that you have already set up the development environment as outlined in the Developer’s Guide. - - -## Create a new `remark` command - -Looking in the `logic.command` package, you will notice that each existing command have their own class. All the commands inherit from the abstract class `Command` which means that they must override `execute()`. Each `Command` returns an instance of `CommandResult` upon success and `CommandResult#feedbackToUser` is printed to the `ResultDisplay`. - -Let’s start by creating a new `RemarkCommand` class in the `src/main/java/seedu/address/logic/command` directory. - -For now, let’s keep `RemarkCommand` as simple as possible and print some output. We accomplish that by returning a `CommandResult` with an accompanying message. - -**`RemarkCommand.java`:** - -``` java -package seedu.address.logic.commands; - -import seedu.address.model.Model; - -/** - * Changes the remark of an existing person in the address book. - */ -public class RemarkCommand extends Command { - - public static final String COMMAND_WORD = "remark"; - - @Override - public CommandResult execute(Model model) { - return new CommandResult("Hello from remark"); - } -} -``` - -### Hook `RemarkCommand` into the application - -Now that we have our `RemarkCommand` ready to be executed, we need to update `AddressBookParser#parseCommand()` to recognize the `remark` keyword. Add the new command to the `switch` block by creating a new `case` that returns a new instance of `RemarkCommand`. - -You can refer to the changes in this [diff](https://github.com/se-edu/addressbook-level3/commit/35eb7286f18a029d39cb7a29df8f172a001e4fd8#diff-399c284cb892c20b7c04a69116fcff6ccc0666c5230a1db8e4a9145def8fa4ee). - -### Run the application - -Run `Main#main` and try out your new `RemarkCommand`. If everything went well, you should see something like this: - -![Output displayed](../images/add-remark/RemarkHello.png) - -## Change `RemarkCommand` to throw an exception - -While we have successfully printed a message to `ResultDisplay`, the command does not do what it is supposed to do. Let’s change the command to throw a `CommandException` to accurately reflect that our command is still a work in progress. - -![The relationship between RemarkCommand and Command](../images/add-remark/RemarkCommandClass.png) - -Following the convention in other commands, we add relevant messages as constants and use them. - -**`RemarkCommand.java`:** - -``` java - public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Edits the remark of the person identified " - + "by the index number used in the last person listing. " - + "Existing remark will be overwritten by the input.\n" - + "Parameters: INDEX (must be a positive integer) " - + "r/ [REMARK]\n" - + "Example: " + COMMAND_WORD + " 1 " - + "r/ Likes to swim."; - - public static final String MESSAGE_NOT_IMPLEMENTED_YET = - "Remark command not implemented yet"; - - @Override - public CommandResult execute(Model model) throws CommandException { - throw new CommandException(MESSAGE_NOT_IMPLEMENTED_YET); - } -``` - -## Enhancing `RemarkCommand` - -Let’s change `RemarkCommand` to parse input from the user. - -### Make the command accept parameters - -We start by modifying the constructor of `RemarkCommand` to accept an `Index` and a `String`. While we are at it, let’s change the error message to echo the values. While this is not a replacement for tests, it is an obvious way to tell if our code is functioning as intended. - -``` java -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; -//... -public class RemarkCommand extends Command { - //... - public static final String MESSAGE_ARGUMENTS = "Index: %1$d, Remark: %2$s"; - - private final Index index; - private final String remark; - - /** - * @param index of the person in the filtered person list to edit the remark - * @param remark of the person to be updated to - */ - public RemarkCommand(Index index, String remark) { - requireAllNonNull(index, remark); - - this.index = index; - this.remark = remark; - } - @Override - public CommandResult execute(Model model) throws CommandException { - throw new CommandException( - String.format(MESSAGE_ARGUMENTS, index.getOneBased(), remark)); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } - - // instanceof handles nulls - if (!(other instanceof RemarkCommand)) { - return false; - } - - RemarkCommand e = (RemarkCommand) other; - return index.equals(e.index) - && remark.equals(e.remark); - } -} -``` - -Your code should look something like [this](https://github.com/se-edu/addressbook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-a8e35af8f9c251525063fae36c9852922a7e7195763018eacec60f3a4d87c594) after you are done. - -### Parse user input - -Now let’s move on to writing a parser that will extract the index and remark from the input provided by the user. - -Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. The class must extend the `Parser` interface. - -![The relationship between Parser and RemarkCommandParser](../images/add-remark/RemarkCommandParserClass.png) - -Thankfully, `ArgumentTokenizer#tokenize()` makes it trivial to parse user input. Let’s take a look at the JavaDoc provided for the function to understand what it does. - -**`ArgumentTokenizer.java`:** - -``` java -/** - * Tokenizes an arguments string and returns an {@code ArgumentMultimap} - * object that maps prefixes to their respective argument values. Only the - * given prefixes will be recognized in the arguments string. - * - * @param argsString Arguments string of the form: - * {@code preamble value value ...} - * @param prefixes Prefixes to tokenize the arguments string with - * @return ArgumentMultimap object that maps prefixes to their - * arguments - */ -``` - -We can tell `ArgumentTokenizer#tokenize()` to look out for our new prefix `r/` and it will return us an instance of `ArgumentMultimap`. Now let’s find out what we need to do in order to obtain the Index and String that we need. Let’s look through `ArgumentMultimap` : - -**`ArgumentMultimap.java`:** - -``` java -/** - * Returns the last value of {@code prefix}. - */ -public Optional getValue(Prefix prefix) { - List values = getAllValues(prefix); - return values.isEmpty() ? Optional.empty() : - Optional.of(values.get(values.size() - 1)); -} -``` - -This appears to be what we need to get a String of the remark. But what about the Index? Let's take a quick peek at existing `Command` that uses an index to see how it is done. - -**`DeleteCommandParser.java`:** - -``` java -Index index = ParserUtil.parseIndex(args); -return new DeleteCommand(index); -``` - -There appears to be another utility class that obtains an `Index` from the input provided by the user. - -Now that we have the know-how to extract the data that we need from the user’s input, we can parse the user command and create a new instance of `RemarkCommand`, as given below. - -**`RemarkCommandParser.java`:** - -``` java -public RemarkCommand parse(String args) throws ParseException { - requireNonNull(args); - ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, - PREFIX_REMARK); - - Index index; - try { - index = ParserUtil.parseIndex(argMultimap.getPreamble()); - } catch (IllegalValueException ive) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - RemarkCommand.MESSAGE_USAGE), ive); - } - - String remark = argMultimap.getValue(PREFIX_REMARK).orElse(""); - - return new RemarkCommand(index, remark); -} -``` - -
- -:information_source: Don’t forget to update `AddressBookParser` to use our new `RemarkCommandParser`! - -
- -If you are stuck, check out the sample -[here](https://github.com/se-edu/addressbook-level3/commit/dc6d5139d08f6403da0ec624ea32bd79a2ae0cbf#diff-8bf239e8e9529369b577701303ddd96af93178b4ed6735f91c2d8488b20c6b4a). - -## Add `Remark` to the model - -Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of person data. We achieve that by working with the `Person` model. Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the person’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a person. - -### Add a new `Remark` class - -Create a new `Remark` in `seedu.address.model.person`. Since a `Remark` is a field that is similar to `Address`, we can reuse a significant bit of code. - -A copy-paste and search-replace later, you should have something like [this](https://github.com/se-edu/addressbook-level3/commit/4516e099699baa9e2d51801bd26f016d812dedcc#diff-41bb13c581e280c686198251ad6cc337cd5e27032772f06ed9bf7f1440995ece). Note how `Remark` has no constrains and thus does not require input -validation. - -### Make use of `Remark` - -Let’s change `RemarkCommand` and `RemarkCommandParser` to use the new `Remark` class instead of plain `String`. These should be relatively simple changes. - -## Add a placeholder element for remark to the UI - -Without getting too deep into `fxml`, let’s go on a 5 minute adventure to get some placeholder text to show up for each person. - -Simply add the following to [`seedu.address.ui.PersonCard`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-639834f1e05afe2276a86372adf0fe5f69314642c2d93cfa543d614ce5a76688). - -**`PersonCard.java`:** - -``` java -@FXML -private Label remark; -``` - - -`@FXML` is an annotation that marks a private or protected field and makes it accessible to FXML. It might sound like Greek to you right now, don’t worry — we will get back to it later. - -Then insert the following into [`main/resources/view/PersonListCard.fxml`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-d44c4f51c24f6253c277a2bb9bc440b8064d9c15ad7cb7ceda280bca032efce9). - -**`PersonListCard.fxml`:** - -``` xml -