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.
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
andUI
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:
-
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]…
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 eithercows
orbrush
-
tasks find t/farm t/land
Displays all tasks that contains either thefarm
orland
tags. -
tasks find n/Cows t/farm
Displays all tasks whose name containsCows
and has thefarm
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
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 internalfilteredTasks
list with the predicate given. Exposed through theModel
interface. -
ModelManager#getFilteredTaskList()
— Returns an unmodifiable view of the internalfilteredTasks
list that updates with any changes to the baselist. Exposed through theLogic
andModel
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.
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.
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.
|
4.2.2. Design Considerations
Aspect: Updating of UI when list is filtered
-
Alternative 1 (current choice): Using
ObservableList
andListView
from JavaFX in UI component.-
Pros:
-
Automatically updates
ListView
when changes are made toObservableList
, no manual events are needed. -
Addition, updates and deletion of tasks will only need to interface with
Logic
andModel
.
-
-
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 oldTask
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
-
Searching for tasks
-
Prerequisites: There are multiple tasks in the list for visible results.
-
Test case:
tasks find n/work
Expected: Any tasks withwork
in the name are listed in the tasks list panel. Number of tasks listed is shown in the status message. -
Test case:
tasks find t/farm
Expected: Any tasks with thefarm
tag are listed in the tasks list panel. Number of tasks listed is shown in the status message. -
Test case:
tasks find sd/20180105
Expected: Any tasks that starts at20180105
are listed in the tasks list panel. Number of tasks listed is shown in the status message. -
Test case:
tasks find n/hello sd/20181103
Expected: Any tasks withhello
in the name and start date20181103
are listed in the tasks list panel. Number of tasks listed is shown in the status message. -
Test case:
tasks find t/
Expected: Task list is not changed. Error details is shown in the status message. -
Other incorrect commands to try:
tasks find n/
,tasks find sd/invaliddate
,tasks find ed/
Expected: Similar to previous.
-