By: SC09-F14-3
Since: Aug 2019
Licence: MIT
1. Setting up
Refer to the guide here.
2. Design
2.1. Architecture
The Architecture Diagram given above explains the high-level design of the App.
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components
The first four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete i/1
.
delete i/1
commandThe sections below give more details of each component.
2.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, EngagementListPanel
, StatusBarFooter
, HelpWindow
, Tab
, TabListPanel
, etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder.
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.
2.3. Logic component
The package state contains additional packages that represent state machines for each Command . These packages have been
omitted for brevity.XYZ refers to any arbitrary command. For example: XYZEndState can be AddEndState and XYZCommand can be AddCommand .
|
API :
Logic.java
-
Logic
uses theInteractiveParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding a person). -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. -
In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
2.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the engagement list data.
-
exposes an unmodifiable
ObservableList<Engagement>
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. -
does not depend on any of the other three components.
2.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the engagement list data in json format and read it back.
2.6. Common classes
Classes used by multiple components are in the com.typee.commons
package.
3. Implementation
This section describes some noteworthy details on how certain features are implemented.
3.1. Tab Switch Feature
Tab switch feature is a type of Command that allows users to switch to respective windows for using different features in the system.
Tab switch function is implemented in using both CLI and GUI approach; user can execute tab-switch by typing command in the input text-area or by interaction with the UI component (Button).
3.1.1. Implementation Structure
-
User is required to use a
Command
;TabCommand
in order to switch the window to another window.-
Upon first startup of the system, system will display the
EngagementList
window by default.
-
-
New Ui Model class
Tab
is implemented to contain the respective fxml controller classes in a OOP manner.
MainWindow will have an additional method fetchTabInformation(tabName)
. After the parser executes the TabCommand
, it will return a CommandResult with Tab
property.
System will then check whether the input name matches with one of the tab names in the system. If there is a match, system will fetch the tab information and return the Tab
object. If no match is found, system will return with an empty tab with only name attached.
3.2. Undo/Redo feature
3.2.1. Implementation
The undo/redo mechanism is facilitated by HistoryManager
.
It extends EngagementList
with an undo/redo history, stored internally as an historyList
and versionPointer
.
Additionally, it implements the following operations:
-
HistoryManager#saveState()
— Saves the current engagement list state in its history. -
HistoryManager#undo()
— Restores the previous engagement list state from its history. -
HistoryManager#redo()
— Restores a previously undone engagement list state from its history.
These operations are exposed in the Model
interface as Model#saveEngagementList()
, Model#undoEngagementList()
and Model#redoEngagementList()
respectively.
Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The HistoryManager
will be initialized with the initial engagement list state, and the versionPointer
pointing to that single engagement list state.
Step 2. The user executes delete i/5
command to delete the 5th person in the engagement list. The delete
command calls Model#saveEngagementList()
, causing the modified state of the engagement list after the delete 5
command executes to be saved in the historyList
, and the versionPointer
is shifted to the newly inserted engagement list state.
Step 3. The user executes add t/meeting …
to add a new engagement. The add
command also calls Model#saveEngagementList()
, causing another modified engagement list state to be saved into the historyList
.
If a command fails its execution, it will not call Model#saveEngagementList() , so the engagement list state will not be saved into the historyList .
|
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#undoEngagementList()
, which will shift the versionPointer
once to the left, pointing it to the previous engagement list state, and restores the engagement list to that state.
If the versionPointer is at index 0, pointing to the initial engagement list state, then there are no previous engagement list states to restore. The undo command uses Model#hasNoUndoableCommand() 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 following sequence diagram shows how the undo operation works:
The lifeline for UndoCommand and UndoState should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
The redo
command does the opposite — it calls Model#redoEngagementList()
, which shifts the versionPointer
once to the right, pointing to the previously undone state, and restores the engagement list to that state.
If the versionPointer is at index historyList.size() - 1 , pointing to the latest engagement list state, then there are no undone engagement list states to restore. The redo command uses Model#hasNoRedoableCommand() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.
|
Step 5. The user then decides to execute the command sort p/start o/ascending
. Commands that do not modify the engagement list, such as sort
, will usually not call Model#saveEngagementList()
, Model#undoEngagementList()
or Model#redoEngagementList()
. Thus, the historyList
remains unchanged.
Step 6. The user executes clear
, which calls Model#saveEngagementList()
. Since the versionPointer
is not pointing at the end of the historyList
, all engagement list states after the versionPointer
will be purged. We designed it this way because it no longer makes sense to redo the add d/meeting …
command. This is the behavior that most modern desktop applications follow.
The following activity diagram summarizes what happens when a user executes a new command:
3.2.2. Design Considerations
Aspect: How undo & redo executes
-
Alternative 1 (current choice): Saves the entire engagement list.
-
Pros: Easy to implement.
-
Cons: May have performance issues in terms of memory usage.
-
-
Alternative 2: Individual command knows how to undo/redo by itself.
-
Pros: Will use less memory (e.g. for
delete
, just save the person being deleted). -
Cons: We must ensure that the implementation of each individual command are correct.
-
Aspect: Data structure to support the undo/redo commands
-
Alternative 1 (current choice): Use a list to store the history of engagement list states.
-
Pros: Easy to implement.
-
Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both
historyList
andengagementList
.
-
-
Alternative 2: Use
jdeveloper.history.HistoryManager
for undo/redo-
Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase.
-
Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as
HistoryManager
now needs to do two different things.
-
3.3. Sort feature
3.3.1. Implementation
The sort mechanism is facilitated by EngagementComparator
.
The EngagementComparator
is an enum class that implements Java Comparator<Engagement> and specifies the comparing logic of 8 different orders, namely START_TIME
, START_TIME_REVERSE
, END_TIME
, END_TIME_REVERSE
, ALPHABETICAL
, ALPHABETICAL_REVERSE
, PRIORITY
, and PRIORITY_REVERSE
.
Each positive sequence comparator compares two Engagements
with the field specified within its name in ascending order, and _REVERSE
comparators compare in descending order.
Additionally, the Model
interface is modified to support the following methods:
-
Model#setComparator(Comparator<Engagement>)
— Sets the designated comparator in model. -
Model#updateSortedEngagementList()
— Executes the sorting method with thecurrentComparator
in model to sort the internal list. -
Model#getSortedEngagementList()
— Returns the current internal engagement list as an unmodifiableObservableList
.
These operations are implemented in the ModelManager
class as ModelManager#setComparator(Comparator<Engagement>)
, ModelManager#updateSortedEngagementList()
and ModelManager#getSortedEngagementList()
respectively.
Given below is an example usage scenario and how the sort mechanism behaves at each step.
Step 1. The user launches the application for the first time. The currentComparator
will be initialized as null
.
Step 2. The user executes sort p/priority o/ascending
command to sort the engagement list in ascending order of priority. The sort
command calls Model#setComparator()
, causing the currentComparator
in ModelManager to assume the value EngagementComparator#PRIORITY
. The command then calls Model#updateSortedEngagementList
to execute the sorting.
The parsing of sort follows the interactive parsing structure Typee adopts, where various stages are created while parsing. See Sequence Diagram below.
|
The following sequence diagram shows how the sort operation works:
The lifeline for SortCommand and the 3 Stages should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
Step 3. The user executes add t/meeting … p/high
to add a new engagement. The add
command also calls Model#updateSortedEngagementList()
with currentComparator
, causing the execution of sorting after the new engagement is added to the list, to preserve the current ordering.
If the currentComparator assumes the initial value null when Model#updateSortedEngagementList is called, the method will simply catch the NullPointerException thrown by java.object.requireNonNull which will essentially abort the attempt to sort with an empty catch block. The initial chronological order is preserved in this case.
|
Step 5. The user then decides to execute the command list
. Commands that do not modify the engagement list or alter the order of the list, such as list
, will usually not call Model#setComparator(Comparator<Engagement>)
, or Model#updateSortedEngagementList()
. Thus, the internal ObservableList
remains unchanged.
The following activity diagram summarizes what happens when a user executes a new command:
3.3.2. Design Considerations
Aspect: How sort executes
-
Alternative 1 (current choice): Use the
List.sort(Comparator<T>)
function to sort the list.-
Pros: Has trivial support for features that updates the predicate of
FilteredList
, likeFind
. -
Cons: There is a need to sort the list each time a command that modifies the elements of the list is executed, which may result in performance issues in case the list size is large.
-
-
Alternative 2: Replace the
FilteredList
inModelManager
with aSortedList
.-
Pros: Sorting the list is more intuitive, and the ordering of the engagements is automatically preserved whenever a command that modifies the list elements is executed.
-
Cons: Features like
find
command may lose functionality and needs extra modification.
-
3.4. Engagement Report Generation
This feature allows user to generate a pre-selected engagement in to a report and save it as a document file. The document file will be created in a .pdf format.
3.4.1. Implementation Structure
The feature will be implemented as an additional type of Command; PdfCommand
-
Proposed syntax of the PdfCommand is as follow:
pdf i/ENGAGEMENT_LIST_INDEX t/RECEIVER f/SENDER
.
Util class PdfUtil
will be implemented for handling all pdf document creation related methods. It will be implemented under util
package and it will be able to deliver few essential features
that are necessary for document creation.
-
Able to generate a full report document based on the
Engagement
as input. -
Use different templates for each other types of
Engagement
such asAppointment
,Interview
andMeeting
. Document template will follow general email format: Receiver, Engagement Information written in a table, Sender and signature with address and company logo.To fulfill the document format,
Report
class needs to be implemented in order to model all necessary properties that has to be in the document. It 3 following properties;-
engagement
: specific engagement information to include in the document -
to
: APerson
who is receiving the document -
from
: APerson
who is either a receptionist or a secretary who is sending the document.
-
Below is the sequence diagram for document generation which displays the concept of how this feature will be implemented by multiple interaction between different architecture components.
3.4.2. UI Design
ReportWindow
will be the UI container which helps the user to interact using PdfCommand
.
The window will include dynamic tree-view that is directly linked to the external directory in the file-system; reports/
UI Components & Features
Table below explains the components that are included in the ReportWindow
with its purpose and features.
UI Component | Feature | Purpose | |
---|---|---|---|
|
Button |
Refreshes the tree-view file directory. |
To help user refresh the directory when there is a system glitch or when document (.pdf) is manually added in the |
|
Button |
Deletes the selected document item in the tree-view file directory. |
To assist users who prefer using mouse instead of typing command in keyboard can delete documents easily. |
|
Scrollable Tree View |
1. Displays the list of document generated previously and stored under the directory 2. Each list item is clickable with a mouse click action of opening the document. |
To allow user to manage documents more time efficiently. |
3.5. Calendar Window
The CalendarWindow
provides a visual representation of stored engagements over a monthly period.
Users can choose to change the month being displayed and also open scrolling text windows which
show more detailed descriptions of the stored engagements for a particular day.
3.5.1. Implementation Structure
The CalendarWindow
is part of the MainWindow
. Specifically, it is one possible Tab
which can be
displayed. The CalendarWindow
class and any of its associated UI components can be found under the com.typee.ui.calendar
package.
The following sequence diagram shows the creation of a CalendarWindow
instance when the user switches to the
calendar window tab.
3.5.2. UI Design
The CalendarWindow
class was designed with the observer pattern in mind. The calendar’s display and any open engagements
list windows are automatically updated as engagements are added to or deleted from the application. CalendarDateCell
and
EngagementListViewCell
both have a reference to an ObervableList
of engagements in order to conform to the observer pattern.
The following table shows all UI components which are used and their respective purposes.
UI Component Type | Feature | Purpose | |
---|---|---|---|
|
GridPane |
Displays a grid which represents 35 calendar dates. |
Shows the user the days of the month which is currently being displayed. |
|
StackPane |
Displays the date of a single |
Provides the user with some general engagement information for a particular date. |
|
Button |
Switches the calendar’s display to the previous month. |
Allows the user to navigate to the previous month. |
|
Text |
Indicates the month and year currently being displayed by the calendar window. |
Informs the month and year currently being displayed by the calendar window. |
|
Button |
Switches the calendar’s display to the next month. |
Allows the user to navigate to the next month. |
|
ListView |
Displays a list of engagements for a particular date. |
Lets the user see more detailed information about all of his/her engagements for a particular date |
|
ListCell |
Displays information for a single engagement. |
Allows the user to see detailed information about a single engagement. This is used as the cell factory for ListView. |
3.5.3. Command Execution Workflows
The following are the four commands which interact with CalendarWindow
. They are accompanied by their respective activity diagrams
which are used to model their workflows:
-
CalendarOpenDisplayCommand
— Opens the engagements list window for the specified date.
-
CalendarCloseDisplayCommand
— Closes the engagements list window for the specified date.
-
CalendarNextMonthCommand
— Changes the calendar window’s display to the month after the currently displayed month.
-
CalendarOpenDisplayCommand
— Changes the calendar window’s display to the month prior to the currently displayed month.
3.5.4. Design Considerations
Aspect: Deciding whether to let engagements list windows from other months remain open when changing the displayed month
-
Alternative 1 (current choice): Only engagements list windows from the current month can be opened. Switching to other months causes all opened engagements list windows to be closed.
-
Pros: Easier to implement and does not take up much memory.
-
Cons: Does not let users view engagement lists from different months simultaneously.
-
-
Alternative 2: Letting engagements list windows remain open, regardless of the month, until they are closed by users.
-
Pros: Users are able to view side-by-side comparisons of their engagement lists across different months.
-
Cons: Introduces additional dependencies because many references to
ObervableList
instances must be maintained.
-
Aspect: Information being displayed in each calendar cell
-
Alternative 1 (current choice): Only display the number of engagements for each date.
-
Pros: Does not take up a lot of on-screen space. More detailed information about each day’s engagements can be viewed by opening the engagements list window for that particular date.
-
Cons: The information shown in the calendar window is very generalized.
-
-
Alternative 2: Display the descriptions (and maybe more detailed information) of each date’s engagements.
-
Pros: Shows more detailed information in the calendar window.
-
Cons: Might end up distorting the shape of the calendar window’s cells since some engagements have more information than others. The alternative would be to add fixed constraints to the size of each cell but then information would get cut off.
-
3.6. Game Feature
3.6.1. Implementation
The game feature is implemented using the singleton pattern using the singleton class GameWindow
which is created
by button-click in StartWindow
. This means that there can only be one gameInstance
at any given time with the exception
of the game being over. The two diagrams below show the UML sequence diagram and activity diagram of the game window, which
gives a high level overview of the game.
GameWindow
has three main components PlayerInformation
, GameBody
and Player
.
The component GameBody
makes use of javafx.animation.AnimationTimer
API to continuously loop MovingWords
objects moving from top
to bottom of the window using GameBody#loopWords()
. MovingWords
are created using
HighlighterUtil#convertToTextFlowUsing(String word)
, which appears as a TextFlow
object of javafx.scene.text
API.
Player input is represented as a javafx.beans.property.StringProperty
in Player
.
Based on player input, MovingWords
are updated using
HighlighterUtil#convertToTextFlowUsing(String playerInput, String word)
, which appears as a highlighted TextFlow
object. In order to update the MovingWords
object, the API
javafx.animation.AnimationTimer
is used by calling MovingWords#continuouslyUpdate()
.
The component PlayerInformation
is bound to Player
using javafx.beans.property
API and is also updated when
MovingWords#continuouslyUpdate()
is called.
The table below summarises the various purposes of the 3 main Game Window UI components.
UI Component Type | Feature | Purpose | |
---|---|---|---|
|
Scrollable Stack Pane |
Displays the user’s score and health points. |
To inform user about the in-game progress. |
|
AnchorPane |
Displays the animation of the game. |
To allow the user to view the animation of the moving words in a continuous manner. |
|
Scrollable Stack Pane |
Displays the individual word. |
To allow user to know the next word to type. |
3.6.2. Design Considerations
Aspect: Singleton pattern design of Game Window
-
Alternative 1 (current choice): Game Window with Singleton pattern design
-
Pros:
-
Prevent users from instantiating multiple Game Windows which may cause performance issues or even cause the application to crash.
-
-
Cons:
-
Reduced testability as it is difficult to replace Singleton objects with stubs, and increased coupling across code base.
-
-
-
Alternative 2: Game Window without Singleton pattern design
-
Pros: Increased testability and reduced coupling.
-
Cons: There could be the risk of users being able to instantiate hundreds or thousands of GameWindows which would cause performance issues or application crash issues.
-
3.7. Interactive Parsing
3.7.1. Overview
Interactive parsing allows users to build a command sequentially, as opposed to doing it entirely in one shot. A user that wishes to
add an interview can simply type add t/interview
to receive prompts on what to enter next.
This feature was conceived to make the application easy to use for amateur users.
3.7.2. Design & Implementation
Important Classes:
-
InteractiveParser
- The interface exposed toLogicManager
. The parser implements this interface. -
Parser
- A concrete implementation ofInteractiveParser
that enables interactive parsing. -
State
- An abstract class that represents the individual states the application can be in while parsing and building aCommand
. -
EndState
- An abstract class that extends fromState
. Represents the finalState
of a parsed command, from which aCommand
object can be built.
The interface InteractiveParser
is the connecting interface between the LogicManager
and the main Parser
. This interface is
designed by contract (DbC - proposed by Bertrand Meyer). The interface exposes four methods to the LogicManager
, namely:
-
parseInput()
- Parses the entered input. -
fetchResult()
- Returns the response to be showed to the user in aCommandResult
object. -
hasParsedCommand()
- Returns true if theParser
has finished parsing aCommand
fully. -
makeCommand()
- Makes and returns theCommand
the user intends to execute.
To achieve interaction, the Parser
keeps track of the State
of the current Command
being built. State
is an abstract class that represents
the individual states the application can be at in the midst of building a Command
. EndState
is an abstract class that extends from State
,
from which Command
objects can be built. As and when valid inputs are entered, the Parser
updates
the current State
to the subsequent States
of the corresponding Command
.
The Parser
starts at an idle, inactive State
Upon entering add t/meeting
, the State
being tracked is changed twice - first
to the State
corresponding to the type of the Engagement
and then to the State
responsible for the start date-time.
Such State
changes happen sequentially until all the arguments necessary for the Command
have been supplied. When all necessary arguments are present,
the State
being tracked transitions into an EndState
. Once the tracked State
transitions into an EndState
, the Parser
builds the Command
which is executed by the LogicManager
.
The structure of the interactive parser is detailed in the UML diagram below.
State
.
The above diagram only shows the component of the package State that handles the PdfCommand . The other packages have been
omitted for brevity.
|
Parsing of user entered inputs can be viewed as parsing a small, finite context-free language. The command built by a sequence of inputs
is uniquely determined by the sequence of inputs entered by the user and happens to be deterministic.
This observation allows the Parser
to be modeled by a finite state machine. A finite state machine is an
abstract computational model which consists of a machine comprising several states. At a particular point in time, only one state
of the state machine is active. The machine transitions from one state to another state if certain conditions are met.
In the context of Typee’s Parser
, the parser of each individual Command
is a distinct finite state machine. The condition to be
satisfied to transition to another state is the validation of user-entered inputs.
The incorporation of state machines into the Parser
is done by implementing a slightly modified version of the state pattern
documented by the Gang of Four (GoF).
Upon initiating the parsing (building) of a Command
, the state machine that corresponds to the required Command
is instantiated and set
to its initial state. This state becomes the State
tracked by the Parser
Subsequent inputs are tokenized by the ArgumentTokenizer
class,
processed by the InputProcessor
class and forwarded to the current State
. If the input is deemed valid, the Parser
invokes the transition()
method of the current State
to proceed to the next State
. This process is repeated until an EndState
is reached. Throughout this process, the
user receives feedback from the Parser
in the form of an encapsulated CommandResult
object.
Below is a sequence diagram illustrating the processes that occur when the user enters add t/meeting s/15/11/2019/1500 e/15/11/2019/1600
.
Parser
parses the entered input and returns the result to the GUI in the form of a CommandResult
object.
The sequence diagram incorrectly extends the life-line of the three destroyed State classes. This is due to a limitation of PlantUML.
|
The high-level working of the Parser
can be summarized by the activity diagram shown below.
"parameter present" refers to the parameter required by a particular state. |
3.7.3. Design Considerations
Aspect : Abstract model
-
Alternative 1 (current design) : Finite state machine
-
Pros:
-
Highly flexible - Entire command, one argument at a time and multiple arguments at a time - all are supported.
-
Easily extensible - Adding a new command will require almost no changes in any of the existing classes.
-
Supports optional arguments with the help of the
OptionalState
interface.
-
-
Cons:
-
Tedious to implement a state machine for each individual command.
-
-
-
Alternative 2 : Use a list based implementation to keep track of arguments entered.
-
Pros:
-
Easy to implement and keep track of arguments
-
-
Cons:
-
Very hard to implement optional states.
-
Cannot execute commands like
Help
at any point in time without hard-coding it in theParser
.
-
-
3.8. Logging
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 3.9, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
3.9. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
4. Documentation
Refer to the guide here.
5. Testing
Refer to the guide here.
6. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
receptionists / secretaries in corporations.
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
-
requires submitting large amount of structured reports or documents
Value proposition: increase productivity by managing appointments faster than a typical mouse/ GUI driven app and by increasing typing speed.
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
secretary |
add an appointment |
organise and schedule meetings/appointments |
|
secretary |
request ro edit a specific appointment |
fix any misinformation that I typed wrongly |
|
secretary under a busy manager |
find specific appointments fast |
schedule appointments efficiently |
|
secretary |
have the option to clear the appointment list |
restart from scratch |
|
secretary |
undo my previous commands |
recall commands made by mistake |
|
secretary |
redo recalled commands |
retrieve the commands undone by mistake |
|
secretary |
select and delete a specific appointment from the list |
manage inactive or cancelled appointments |
|
busy secretary |
able to see the appointments in calendar view |
enjoy better convenience |
|
user |
save and load data from a local file |
keep the appointment list locally |
|
secretary under a busy manager |
sort all appointments |
see them in the order I want |
|
user |
have a command to terminate the application |
|
|
advanced user |
be able to execute compound statements |
improve efficiency |
|
highly motivated secretary |
have a typing warm-up |
prepare myself for an important events like important meetings. |
|
highly driven secretary |
have a way to practice typing |
improve my efficiency during work by increasing my typing speed |
|
fast-typer |
have a way to amend trivial spelling errors |
improve typing efficiency |
|
secretary |
generate a PDF file of a selected appointment |
make a distributable copy of the appointment |
Appendix C: Use Cases
(For all use cases below, the System is the Typee
and the Actor is the user
,
unless specified otherwise)
Use case: (UC01) Add appointment
MSS
-
User requests to add an appointment.
-
System adds the corresponding appointment to the existing appointment list.
-
System displays the updated appointment list and notifies the user.
Use case ends
Extensions
-
1a. User supplies the necessary information.
Use case ends
-
1b. User supplies invalid information.
-
1b1. System notifies user about the invalid information.
Use case ends
-
-
1c. Appointment clashes with an existing appointment.
-
1c1. System notifies user about the conflict.
Use case ends
-
Use case: (UC02) List appointments
MSS
-
User requests to list appointments
-
System displays the list of appointments
Use case ends.
Extensions
-
1a. The list of appointments is empty
Use case ends.
-
2a. The list is empty
Use case ends.
Use case: (UC03) Find appointment
MSS
-
User requests to find appointments
-
User provides fields that the user wants to use to find appointments
-
System finds and displays the list of relevant appointments
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
Use case: (UC04) Delete appointment
MSS
-
User requests to list appointments
-
System displays the list of appointments
-
User requests to delete a specific appointment in the list
-
System deletes the appointment
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. System shows an error message.
Use case resumes at step 2.
-
Use case: (UC05) Exit application
MSS
-
User requests to exit the application
-
System displays exit message
-
System exits
Use case ends
Use case: (UC06) Request help information
Use case: (UC07) Save updated Appointment data
MSS
-
User make changes in the appointment list, or a specific appointment via CRUD.
-
System saves the updated data
-
System displays the updated appointment data
Use case ends
Use case: (UC08) Edit selected appointment
MSS
-
User requests to list appointments
-
System displays the list of appointments
-
User keys in index and provide fields that the user wants to edit
-
System edits the selected appointment accordingly
Use case ends.
Extensions
-
2a. The list is empty
Use case ends.
-
3a. User keys in invalid index
-
3a1. System shows error message.
Use case resumes at step 2.
-
-
3b. User does not provide any field to edit.
-
3b1. System shows error message.
Use case resumes at step 2.
-
Use case: (UC09) Undo previous command
MSS
-
User requests to undo command
-
System reverts the appointment list to its previous state
Use case ends.
Extensions
-
2a. There is no previous command
Use case ends.
Use case: (UC10) Redo previous command
MSS
-
User requests to redo command
-
System reverts the appointment list to its previous undone state
Use case ends.
Extensions
-
2a. There is no previous undone command
Use case ends.
Use case: (UC11) Switch tabs
MSS
-
User requests to switch to a specified tab.
-
System switches to the appropriate tab.
Use case ends.
Extensions
-
1a. Requested tab is invalid.
-
1a1. System shows error message.
Use case resumes at step 1.
-
Use case: (UC12) Calendar mode
MSS
-
User specifies a date to view engagements for.
-
System shows the engagements for the specified date.
Extensions
-
1a. User specifies an invalid date.
-
1a1. System shows error message.
Use case resumes at step 1.
-
Use case: (UC13) Calendar mode month switching
MSS
-
User specifies a month to switch the display to.
-
System updates the calendar view to display appointments for the specified month.
Extensions
-
1a. User specifies an invalid month.
-
1a1. System shows error message.
Use case resumes at step 1.
-
Use case: (UC14) Typing game
MSS
-
User requests to start the typing game
-
System shows typing game window which displays the specific word(s) to type.
-
User plays the game by typing the word(s).
-
Typing game updates the User’s score and health points accordingly. Steps 2-4 are repeated for as many rounds as required until User runs out of health points.
-
Typing game shows the final score of the User when the game ends.
Use case ends.
Extensions
-
2a. User exits game
Use case ends.
Use case: (UC15) Generate appointment document in PDF format
MSS
-
User enters information for generating PDF of an engagement for a selected engagement.
-
System generates a PDF file in a specific external directory
-
System shows successful message
-
System opens the generated document.
Use case ends.
Extensions
-
2a. System receives invalid input.
-
2a1. System shows error message.
Use case resumes at step 1.
-
-
2b. User inputs duplicate information that already exists in the directory.
-
2b1. System shows error message.
Use case resumes at step 1.
-
Use case: (UC16) Sort appointments
MSS
-
User requests to sort appointments
-
User specifies the property to sort regarding to
-
User specifies the order of ascending or descending
-
System sorts the list of appointments by the specified order
Use case ends.
Extensions
-
2a. User does not specify property
-
2a1. System shows error message
Use case ends.
-
-
2b. User specifies an invalid property
-
2b1. System shows error message
Use case ends.
-
-
3a. User does not specify order
-
3a1. System shows error message
Use case ends.
-
-
3b. User specifies an invalid order
-
3b1. System shows error message
Use case ends.
-
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should come with automated unit tests and open source code.
-
Should work on both 32-bit and 64-bit environments.
-
Application should not exceed 100MB in size.
-
Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
-
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.
Appendix E: Glossary
- Mainstream OS
-
Windows, Linux, Unix, OS-X
- Secretary
-
A person employed by an individual or in an office to assist with correspondence, make appointments, and carry out administrative tasks.
- Manager
-
The person that the secretary is assigned to work for.
- Engagement
-
An arrangement, meeting or interview managed and maintained by a secretary, for the manager to meet someone at a particular time and place.
Appendix F: Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
F.1. Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
F.2. Adding an engagement
(i) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(ii) Test case: add t/ s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid engagement type due to invalid engagement type.
(iii) Test case: add t/meeting s/ e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid start time due to invalid start time.
(iv) Test case: add t/meeting s/16/11/2019/1500 e/ l/Meeting Room 2 d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid end time due to invalid end time.
(v) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/ d/Team Meeting a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for a valid location due to invalid location.
(vi) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/ a/John | Smith p/High
Expected: The engagement is not added. Status bar shows prompt for due to invalid description.
(vii) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/ p/High
Expected: The engagement is not added. Status bar shows prompt for a valid attendees due to invalid attendees.
(vii) Test case: add t/meeting s/16/11/2019/1500 e/16/11/2019/1600 l/Meeting Room 2 d/Team Meeting a/John | Smith p/高
Expected: The engagement is not added. Status bar shows prompt for a valid priority due to invalid priority.
(viii) Test case:
The sequence of commands is as follows:
add
t/meeting
s/16/11/2019/1500
e/16/11/2019/1600
l/Meeting Room 2
d/Team Meeting
a/John | Smith
p/High
Expected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(ix) Test case:
The sequence of commands is as follows:
add
t/appointment
s/01/01/2019/0900
e/01/01/2019/1000
l/Meeting Room 3
d/Team Discussion
a/John Smith
p/None
Expected: Status bar shows the successful addition of engagement with its details. The engagement list is updated accordingly.
(x) Test case:
The sequence of commands is as follows:
add
t/meeting
s/16/11/2019/1500
e/16/11/2019/1600
l/Meeting Room 2
d/Team Meeting
a/John | Smith
p/😄
Expected: The engagement is not added. Status bar shows prompt for a valid priority due to invalid priority.
F.3. Listing an engagement
(i) Test case: list
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
(ii) Test case: 123 list
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
(iii) Test case: list 123
Expected: Status bar shows the successful listing of engagement. The full engagement list is shown.
F.4. Deleting an engagement
(i) Test case: delete i/3
Expected: If there are 3 or more engagements in the engagement list, the 3rd engagement is deleted. Status bar shows the successful deletion of engagement with its details. The engagement list is updated accordingly. Otherwise, the engagement is not deleted due to invalid index.
(ii) Test case:
The sequence of commands is as follows:
delete
i/3
Expected: If there are 3 or more engagements in the engagement list, the 3rd engagement is deleted. Status bar shows the successful deletion of engagement with its details. The engagement list is updated accordingly. Otherwise, the engagement is not deleted due to invalid index.
(ii) Test case: delete i/-1
Expected: The engagement is not deleted due to invalid index.
(iii) Test case:
The sequence of commands is as follows:
delete
i/-1
Expected: The engagement is not deleted due to invalid index.
F.5. Finding an engagement
(i) Test case: find d/Singapore based
Expected: Engagements containing description keyword will be shown. e.g. will show
all engagements containing the description Singapore based
.
e.g. singapore based internship appointment
, Singapore based project meeting
(ii) Test case:
The sequence of commands is as follows:
find
d/Singapore based
Expected: Engagements containing description keyword will be shown. e.g. will show
all engagements containing the description Singapore based
.
e.g. singapore based internship appointment
, Singapore based project meeting
(iii) Test case: find l/Com Basement
Expected: Engagements matching the full exact keyword will be shown. e.g. will show
all engagements containing the location Com Basement
. Note that engagement with location Basement Room 6
will not be shown.
(iv) Test case:
The sequence of commands is as follows:
find
l/Com Basement
Expected: Engagements matching the full exact keyword will be shown. e.g. will show
all engagements containing the location Com Basement
. Note that engagement with location Basement Room 6
will not be shown.
(v) Test case: find a/Hans
Expected: Engagements containing attendee keyword will be shown. e.g. find a/Hans
will show
all engagements containing the attendee Hans
.
e.g. Hansen Gruber
, hans christian
(vi) Test case: find a/Hans
The sequence of commands is as follows:
find
a/Hans
Expected: Engagements containing attendee keyword will be shown. e.g. find a/Hans
will show
all engagements containing the attendee Hans
.
e.g. Hansen Gruber
, hans christian
(vii) Test case: find p/High
Expected: Engagements containing high priority will be shown.
(viii) Test case:
The sequence of commands is as follows:
find
p/High
Expected: Engagements containing high priority will be shown.
(ix) Test case: find a/Hans p/high
Expected: Engagements containing the attendee Hans
and with high priority will be shown.
(ix) Test case:
The sequence of commands is as follows:
find
a/Hans p/high`
Expected: Engagements containing the attendee Hans
and with high priority will be shown.
F.6. Sorting the engagement list
(i) Test case:
The sequence of commands is as follows:
sort
p/start
o/ascending
Expected: The list should be sorted in ascending order of start time.
(ii) Test case: Executing the sort command by giving all attributes at once
sort p/start o/ascending
Expected: This should give the exact same result as the previous stepwise command.
F.7. Undo and Redo
(i) Test case: Executing the undo command
The sequence of commands is as follows:
delete i/1 (provided there is at least 1 engagement in the list)
undo
Expected: The previously deleted engagement should reappear in the list.
(ii) Test case: Executing the redo command
The sequence of commands is as follows:
delete i/1 (provided there is at least 1 engagement in the list)
undo
redo
Expected: The recovered engagement should disappear in the list.
F.8. Calendar commands
All listed commands assume that the application is in the calendar tab.
(i) Test case:
The sequence of commands is as follows:
calendar c/opendisplay d/11/11/2019
Expected: The engagements display window for 11/11/2019 opens up.
(ii) Test case:
The sequence of commands is as follows:
calendar c/closedisplay d/11/11/2019
Expected: When executed immediately after executing the command in (i), the engagements display window for 11/11/2019 closes.
(iii) Test case:
The sequence of commands is as follows:
calendar c/opendisplay d/10/10/2019
Expected: The calendar window switches from the currently displayed month (assuming that it is not displaying October 2019) to October 2019. The engagements display window for 10/10/2019 opens up.
(iii) Test case:
The sequence of commands is as follows:
calendar c/nextmonth
Expected: All open engagements list windows are closed and the calendar displays the month after the currently displayed month.
(iv) Test case:
The sequence of commands is as follows:
calendar c/previousmonth
Expected: All open engagements list windows are closed and the calendar displays the month prior to the currently displayed month.
F.9. Tab
(i) Test case: tab b/engagement
Expected: The current tab switches to engagement tab
(ii) Test case: tab b/calendar
Expected: The current tab switches to calendar tab
(iii) Test case: tab b/game
Expected: The current tab switches to game tab
(iv) Test case: tab b/report
Expected: The current tab switches to report tab
F.10. Game
(i) Test case: Click on Start
button of the starting window of the game tab.
Expected: New game window opens.
(ii) Test case: Click on Close
button of the game window.
Expected: Game window closes.
F.11. Generating PDF
(i) Test case:
pdf
i/1 (provided at least 1 engagement in the list)
f/Jason
t/Gi Hun
Expected: A PDF file is generated with the content of the first engagement in list, with sender set to Gi Hun and reciver set to Jason. The file can be seen in the documents explorer tree view.
(ii) Test case:
Click the refresh button
Expected: Documents explorer tree view refreshes.
(iii) Test case:
Single click on an existing document in documents explorer tree view
Click the delete button
Select OK in pop-up dialog
Expected: Selected document is deleted from directory.
(iv) Test case:
Double click on an existing document in documents explorer tree view
Expected: Selected document opens in the default .pdf
file viewer