jaypeeteedee

Hello! I am John Phua, a Year 2 Computer Science undergraduate student at the National University of Singapore. Over the semester, my team and I built Cow, a project management application. This portfolio will introduce you to Cow and my contributions towards its development.

PROJECT: Cow

1. Overview

Cow is a desktop task manager with project management capabilities, powered by a command-line interface. It is written in Java by a team of 5 undergraduates from the NUS School of Computing.

Ui

By entering commands, Cow allows you to efficiently:

  • Manage a list of tasks

  • Manage a list of group members across different project groups

  • Assign tasks to people

  • View the monthly workload of people through a calendar view

2. Summary of contributions

  • Major feature: Searching of tasks by name, date and tags

    • Purpose: Allowing you to efficiently search for tasks

    • Value to project: Task lists can get long and cluttered, this feature allows you to easily filter through your long list of tasks and retrieve what you want.

    • Highlights: This feature was built to be flexible according to your needs. You can combine different search criteria to make your search more specific. This required the design of a new class that can accept and compound different search criteria together.

  • Code contributions: [All code commits] [Project Dashboard View]

  • Other contributions:

    • Project management:

      • Managed releases v1.2 - v1.3 (2 releases) on GitHub

    • Enhancements to existing features:

      • Implemented initial Storage and UI components for tasks (Pull request #12)

      • Updated and maintained the graphical user interface for the list of tasks (Pull requests #57, #90, #103)

      • Wrote task UI handlers for testing (Pull requests #91)

      • Wrote tests for my features that increased code coverage from 71% to 75% (Pull request #162)

    • Documentation:

      • Updated calendar commands in User Guide (Pull request #31)

      • Added guide for finding tasks in User Guide (Pull request (Pull request #100)

      • Added the implementation of listing and finding tasks in the Developer Guide (Pull request #66)

    • Tools:

      • Configured Reposense to track contributions from the team.

3. Contributions to the User Guide

You can see my contributions to the User Guide for Cow below. They showcase my ability to write documentation that is easy for end-users to follow and understand, while accounting for possible errors in usage.

3.1. Search for tasks: tasks find

Find tasks based on name, start date, end date and/or tags.
When the command is entered, you should see the list of tasks update to show only the tasks that match your search request.

Format: tasks find [n/KEYWORD]…​ [sd/START_DATE] [ed/END_DATE] [t/TAG]…

  • Searching by keyword is case insensitive. e.g cows will match Cows

  • Only full words will be matched. e.g. Cow will not match Cows

  • Providing multiple keywords or tags will return tasks that match any of the keywords or tags.
    e.g. tasks find n/cow n/farm will search for tasks with either cow or farm in the name.

  • Providing multiple start dates or end dates will only use the last one for filtering.
    e.g. tasks find ed/20181130 ed/20181212 will search with end date 20181212.

  • Searching based on different criteria will return tasks that match all criteria.
    e.g. Searching on start date and end date will return tasks that match both.

Examples:

  • tasks find ed/20181130
    Displays all tasks whose end date is 30 November 2018

  • tasks find n/cows n/brush
    Displays all tasks whose name contains either cows or brush

  • tasks find t/farm t/land
    Displays all tasks that contains either the farm or land tags.

  • tasks find n/Cows t/farm
    Displays all tasks whose name contains Cows and has the farm tag.

4. Contributions to the Developer Guide

You can see my contributions to the Developer Guide for Cow below. They showcase my ability to communicate technical concepts to other developers and the technical depth of my contributions to the project.

4.1. Storage component

StorageClassDiagram
Figure 1. Structure of the Storage Component

API : Storage.java

The Storage component,

  • can save UserPref objects in json format and read it back.

  • can save the Address Book data in xml format and read it back.

XmlAdaptedPerson depends on XmlAdaptedTaskId to keep track of tasks assigned to the person.
XmlAdaptedTask depends on XmlAdaptedPersonId to keep track of persons assigned to the task.

4.2. Listing and finding of tasks

4.2.1. Current Implementation

Listing and finding of tasks is facilitated by ModelManager and displayed through TaskListPanel.

ModelManager implements the following relevant methods:

  • ModelManager#updateFilteredTaskList(Predicate<Task> predicate) — Updates the the internal filteredTasks list with the predicate given. Exposed through the Model interface.

  • ModelManager#getFilteredTaskList() — Returns an unmodifiable view of the internal filteredTasks list that updates with any changes to the baselist. Exposed through the Logic and Model interfaces.

ModelManager#filteredTasks is a JavaFX FilteredList around the unmodifiable list of tasks provided by VersionedAddressBook#getTaskList()).

TaskListPanel is constructed with the JavaFX ObservableList returned by ModelManager#getFilteredTaskList() when the application is started and displays it.

To find specific tasks, the appropriate predicate is passed into ModelManager#updateFilteredTaskList(), which updates the filteredTasks list, propagating the change up to the TaskListPanel display.

TaskListFindModelSequenceDiagram
Figure 2. Filtering of Tasks in Model Component

Currently, there are 2 use cases where ModelManager#updateFilteredTaskList() is called, examples are given below.

Case 1: On application startup or after running tasks list command

ModelManager#updateFilteredTaskList() is called with Model#PREDICATE_SHOW_ALL_TASKS which returns true for all tasks.

TaskListLogicSequenceDiagram
Figure 3. Sequence Diagram of Tasks List Command

Case 2: After running tasks find [n/KEYWORD]…​ [sd/START_DATE] [ed/END_DATE] [t/TAG]… command

ModelManager#updateFilteredTaskList() is called with predicate built by TaskPredicateAssembler which combines the different predicates from input.

TaskPredicateAssembler combines the following predicates:

  • NameContainsKeywordsPredicate: Returns true if tasks name contains any of the full keywords

  • MatchesStartDatePredicate: Returns true if start date of task matches input

  • MatchesEndDatePredicate: Returns true if end date of task matches input

  • HasTagsPredicate: Returns true if task contains any of the specified tags

TaskFindLogicSequenceDiagram
Figure 4. Sequence Diagram of Tasks Find Command

4.2.2. Design Considerations

Aspect: Updating of UI when list is filtered
  • Alternative 1 (current choice): Using ObservableList and ListView from JavaFX in UI component.

    • Pros:

      • Automatically updates ListView when changes are made to ObservableList, no manual events are needed.

      • Addition, updates and deletion of tasks will only need to interface with Logic and Model.

    • Cons:

      • ObservableList does not raise change events when tasks in the base list are mutated. Any edits to existing tasks will need to replace the old Task instance with a new one for changes to be reflected on the UI.

  • Alternative 2: Using Java List in UI component.

    • Pros:

      • Does not enforce immutability on tasks.

      • Full control over when and what UI should update.

    • Cons:

      • Events will need to be raised manually when tasks are changed.

Aspect: Filtering of lists
  • Alternative 1 (current choice): Using FilteredList from JavaFX.

    • Pros:

      • Convenient as the filter is maintained even when the base list is changed.

      • Abstracts away filtering logic, only need to be concerned with the predicate used.

      • Any filter updates will automatically update UI as it implements ObservableList.

    • Cons:

      • Only works as a simple filter.

  • Alternative 2: Using Streams from Java.

    • Pros:

      • Powerful, can also be used to transform tasks as an intermediate operation.

    • Cons:

      • For the same predicate, a new stream will need to be made when the task list is changed.

      • Events will need to be raised to update UI on newly filtered list of tasks.

4.2.3. Future Enhancements

Currently, searching by task name only matches full keywords. In the future, part of words can be matched to allow users to search with incomplete keywords.

4.3. Filtering tasks

  1. Searching for tasks

    1. Prerequisites: There are multiple tasks in the list for visible results.

    2. Test case: tasks find n/work
      Expected: Any tasks with work in the name are listed in the tasks list panel. Number of tasks listed is shown in the status message.

    3. Test case: tasks find t/farm
      Expected: Any tasks with the farm tag are listed in the tasks list panel. Number of tasks listed is shown in the status message.

    4. Test case: tasks find sd/20180105
      Expected: Any tasks that starts at 20180105 are listed in the tasks list panel. Number of tasks listed is shown in the status message.

    5. Test case: tasks find n/hello sd/20181103
      Expected: Any tasks with hello in the name and start date 20181103 are listed in the tasks list panel. Number of tasks listed is shown in the status message.

    6. Test case: tasks find t/
      Expected: Task list is not changed. Error details is shown in the status message.

    7. Other incorrect commands to try: tasks find n/, tasks find sd/invaliddate, tasks find ed/
      Expected: Similar to previous.