Overview
EventOrganiser is a desktop application for organisation and management of events. 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.
Summary of
-
Major enhancement: added Event and Poll commands and functionality.
-
What it does: Event-related commands allow event organisers to create, edit and manage events, and users to find and join events. Poll-related commands allow the event organiser to create polls and for participants to vote in the poll.
-
Justification: Events are essential to the event organiser. Polls in the Event are useful for event organisers to decide on a suitable activity, date and time for the event.
-
Highlights:
-
Updated all components: logic, model, storage, UI to support events and polls
-
Integrated Persons into Events: Persons are stored in events by index in storage and in runtime, and events are updated when user are edited or deleted.
-
Implemented dependencies between commands e.g. users should select events before editing
-
-
-
Code contributed: [Functional code]
-
Other contributions:
-
Project management:
-
Pushed tags and closed milestones for v1.1 and v1.2 to GitHub.
-
Created PR from team-repo to AB4.
-
Assigned issues after PE dry-run: issue tracker
-
Updated AboutUs.doc: #3
-
Updated ReadMe: #10
-
Updated sample data: #165
-
-
Documentation:
-
Contributed to portions of User Guide and Developer Guide relevant to my own features as well as User Guide overview. Links can be found below.
-
Contributed to initial draft of User Guide and Developer Guide (e.g. use cases): #3
-
-
Community:
-
Contributions to the User Guide
Given are excerpts from the sections which I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
How it works, in brief
-
To use the application, you must first create an account using the
addUser
command, and thenlogin
. -
If you are not yet logged in, you can still view event details using
selectEvent
, and find events usingfindEvent
andfindEventByTime
, and list events usinglistEvent
. -
Without logging in, you can also use the
selectUser
,findUser
,listUser
,listFriends
,suggestFriendsByInterests
commands. -
When you are done, simply
logout
orexit
the application.
Organise an event
-
If you are looking to organise an event, you may do so using the
addEvent
command. -
After creating the event, you may wish to specify the date, time, or specify only after participants have joined.
-
You may create polls to get participants to vote on the details of the event using
addPoll
andaddPollOption
. -
You can create a special TimePoll using
addTimePoll
after all participants have joined to decide on a suitable time. This generates poll options based on the NUSMOD schedules of the participants. -
You may decide to
deleteEvent
after the event is over, or leave it in the organiser as a form of record.
Join an event
-
If you are looking to join an event as a participant, you may search for an event to join using the
findEvent
andfindEventByTime
commands. -
You can also search for other users using the
findUser
andlistFriends
commands to see what events they have joined and join that event as well. -
After joining the event using
joinEvent
, you can vote in the polls by displaying the poll details usingdisplayPoll
. -
You can then add options using
addOption
, or simply vote for an option usingvote
.
Create and confirm event commands
Create a new event : addEvent
Adds a new event to EventOrganiser.
Format: addEvent n/NAME a/LOCATION [t/TAG] …
Examples:
-
addEvent n/NUS Tennis Welcome Session a/SOC Canteen t/Public
-
addEvent n/CS1101S Meet-up a/UTown t/ByInvite
Delete an event : deleteEvent
Deletes the specified event from EventOrganiser.
Format: deleteEvent INDEX
Examples:
-
listEvent
deleteEvent 2
Deletes the 2nd event in EventOrganiser.
Select an event : selectEvent
Selects an event to be edited.
Format: selectEvent INDEX
Create a new poll for an event : addPoll
Sets up a new poll for the pre-selected event with the specified name.
Format: addPoll n/POLL_NAME
-
addPoll n/Date
Upon adding a new poll, only the index and name of the poll is displayed, as shown. The event organiser can then proceed to add options to the poll. Selecting the event again using theselectEvent
command displays the list of all polls in the event.
Create a new time-based poll for an event : addTimePoll
Sets up a new time-based poll for the event with the specified name after all users have joined.
Format: addTimePoll d1/DAY-MONTH-YEAR d2/DAY-MONTH-YEAR
Examples:
-
addTimePoll d1/08-09-2018 d2/10-09-2018
Add options to poll : addOption
Add new poll option in the specified poll.
Format: addOption i/POLL_INDEX o/POLL_OPTION
Examples:
-
addOption i/1 o/Play chess
Adds an option to the first poll of the selected event, where the option isPlay chess
. This option would be relevant in the context of a poll for an appropriate activity. -
addOption i/3 o/12 November
addOption i/3 o/13 November
In the following example, the options12 November
and13 November
have been added to the poll. Since there are no voters yet, the most popular options list is empty.
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Poll feature
Current implementation
This section explains the implementation of the features associated with the Poll class of each Event while detailing some implementation details of the Event class. The relevant commands which are callable by the user to be discussed are:
-
AddPollCommand
- adds a new Poll to the event given the name of the poll to be created. -
AddPollOptionCommand
- adds a new poll option to the poll given the poll index and the name of the option to be added. -
VoteCommand
- adds the current user as a voter to the voter list of the given option. -
AddTimePollCommand
- creates a new TimePoll automatically populated with options based on the schedules of the event participants.
For all the above commands, the event must first be selected using the selectEvent
command, which will set the currentEvent
through the Model#setSelectedEvent()
method.
This is done to ensure that users do not have to continually specify the event for which the Poll commands are called for every command.
This is on top of the currentUser
in the Model which was already selected through the LoginCommand
.
There are two types of Polls which extends from the abstract class AbstractPoll: Poll and TimePoll.
Each AbstractPoll object contains a pollData
attribute which is stored as a HashMap<String, UniquePersonList>
.
The pollData
stores each option as a string and the list of voters to that particular option as a UniquePersonList.
As can be seen in the class diagram, AbstractPolls also include a unique ID to identify the poll and a poll name.
They also support the adding of votes by participants who have joined the event, and the display of the poll details, including the most popular options.
The TimePoll
class extends from the abstract AbstractPoll
class which is constructed by calling the AddTimePollCommand
.
This command automatically generates a list of 30 minute time slots based on the schedules of the persons on the event invite list,
and a specified date range in the user input. The two dates must not be more than a month apart.
The TimePoll shares most of its functionality with Poll, except that users may not add new options. The TimePoll does not automatically update when new event participants join the event. This is done in order to present existing votes for certain options being removed when additional participants join the event. Hence, the event organiser must wait for all participants to be confirmed before adding a TimePoll.
When storing the Poll object in the Storage component, since the XML format does not support the HashMap format,
each entry of the HashMap must be converted to a XmlAdaptedPollEntry.
Each XmlAdaptedPollEntry contains the option as a String as well as a list of XmlPersonIndex objects,
which serve as pointers to the actual Person objects stored in EventOrganiser.
Hence, when the EventOrganiser data is retrieved from storage, the Persons in the list of voters for each option, as well as the Persons in the event participant list,
refer to the same Person objects in the list of users of the EventOrganiser.
This ensures that when a user is edited or deleted, they are updated or deleted in the poll details accordingly.
This functionality is supported by the AbstractPoll#updatePerson()
and AbstractPoll#deletePerson()
methods.
As an example, the following sequence diagram illustrates the workings of the VoteCommand
.
As stated above, since Model already stores the current user and the selected event from prior user commands,
the Model can call the correct Event e
and currently logged-in user
in the addVoteToPoll
method. If there is no logged-in user,
a NoUserLoggedInException
is thrown, and if there is no selected event, a NoEventSelectedException
is thrown.
In addition, four other possible exceptions might be thrown by the VoteCommand:
-
A user must have already joined the event as a participant, or be on the invite list in order to vote, failing which, a UserNotJoinedEventException is thrown.
-
A user must not already have voted for that particular option in the poll already. This is enforced by the UniquePersonList, which throws a DuplicatePersonException if someone tries to vote twice.
-
A poll must exist at the given poll index for the selected event, else, an IndexOutOfBoundsException is thrown.
-
The given option must exist in the selected poll, else, an IllegalArgumentException is thrown.
The other commands AddPollCommand
and AddPollOptionCommand
follow a very similar structure.
The sequence diagram within the model for the AddPollCommand
is illustrated here:
In all cases, the contents of the poll is returned to the calling Command object as String through the Poll#displayPoll()
method.
The displayed details of the poll contains the most popular options, computed using the Poll#getPopularOptions()
method.
This method returns an empty list if no user has voted for any option yet, i.e. if the most popular option has no voters.
A new DisplayPollEvent
is then posted to the EventsCenter, which is handled by the PollDisplayPanel in the UI component.
Design considerations
Aspect: The relationship between Poll
and TimePoll
-
Alternative 1 (Current implementation): Design them as separate classes which both inherit from an abstract
AbstractPoll
class.-
Pros: Allows for future extendability from the AbstractPoll class eg additional types of Polls (location, date) which constrain the option types and include additional features to recommend the best option eg most convenient location by distance for participants.
-
-
Alternative 2: Allow
TimePoll
to extend from thePoll
class.-
Pros: The two classes differ only in that
TimePoll
has the augmented feature of generating options from the schedule of event participants. -
Cons: Unable to constrain the input and prevent users from adding the wrong format for options into
TimePoll
, since this would violate the Liskov Substitution Principle.
-
Aspect: Storage of voters in Poll
-
Alternative 1 (Current implementation): Store the voters as Persons.
-
Pros: All information about the voters are stored. This also allows the application to distinguish between two users of the same name. Future extensions to the application might also require additional details about the voters.
-
Cons: Need for complete reference to the actual person via the XmlPersonIndex class in storage, rather than duplicating the person details. The voter list must also be manually updated every time the person details are updated.
-
-
Alternative 2: Store only the names of voters.
-
Pros: No need for complete reference to the actual person via the XmlPersonIndex class in storage.
-
Cons: Some persons might share the same name. It is also not extendable for future versions where the data/attributes of the voters might be relevant to computing the best option.
-