Skip to content

Commit

Permalink
Merge pull request #124 from AY1920S1-CS2103T-W11-2/add-view-command
Browse files Browse the repository at this point in the history
Add View command and UI to display details of Activity and Person
  • Loading branch information
liakify authored Oct 29, 2019
2 parents 31149c6 + b1bdbb1 commit 584781e
Show file tree
Hide file tree
Showing 62 changed files with 1,511 additions and 198 deletions.
5 changes: 3 additions & 2 deletions src/main/java/seedu/address/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
*/
public class Messages {

public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command";
public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command!";
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
public static final String MESSAGE_INVALID_ACTIVITY_DISPLAY_INDEX = "The activity index provided is invalid!";
public static final String MESSAGE_INVALID_PERSON_DISPLAY_INDEX = "The person index provided is invalid!";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";

}
13 changes: 13 additions & 0 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.address.logic;

import java.nio.file.Path;
import java.util.List;

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
Expand Down Expand Up @@ -37,6 +38,18 @@ public interface Logic {
/** Returns an unmodifiable view of the filtered list of activities */
ObservableList<Activity> getFilteredActivityList();

/**
* Returns an unmodifiable list of {@code Person} containing all participants of a
* specified {@code Activity}.
*/
List<Person> getAssociatedPersons(Activity activity);

/**
* Returns an unmodifiable list of {@code Activity} containing all activities a specified
* {@code Person} has participated in.
*/
List<Activity> getAssociatedActivities(Person person);

/**
* Returns the user prefs' address book file path.
*/
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.logging.Logger;

import javafx.collections.ObservableList;
Expand Down Expand Up @@ -73,6 +74,16 @@ public ObservableList<Activity> getFilteredActivityList() {
return model.getFilteredActivityList();
}

@Override
public List<Person> getAssociatedPersons(Activity activity) {
return model.getAssociatedPersons(activity);
}

@Override
public List<Activity> getAssociatedActivities(Person person) {
return model.getAssociatedActivities(person);
}

@Override
public Path getAddressBookFilePath() {
return model.getAddressBookFilePath();
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/seedu/address/logic/commands/CommandResult.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.util.Objects;
import java.util.Optional;

import seedu.address.model.ContextType;
import seedu.address.model.Context;

/**
* Represents the result of a command execution.
Expand All @@ -20,8 +21,8 @@ public class CommandResult {
/** The application should exit. */
private final boolean exit;

/** Type of updated context - empty if context was not changed by executing this command. */
private final Optional<ContextType> newContext;
/** Updated application context - empty if context was not changed by executing this command. */
private final Optional<Context> newContext;

/**
* Constructs a {@code CommandResult} with the specified fields, for commands that does not change
Expand All @@ -40,8 +41,8 @@ public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) {
* @param feedbackToUser {@code String} output from executing the command
* @param newContext the new {@code ContextType} after executing the command
*/
public CommandResult(String feedbackToUser, ContextType newContext) {
requireNonNull(newContext);
public CommandResult(String feedbackToUser, Context newContext) {
requireAllNonNull(feedbackToUser, newContext);
this.feedbackToUser = requireNonNull(feedbackToUser);
this.showHelp = false;
this.exit = false;
Expand All @@ -68,7 +69,7 @@ public boolean isExit() {
return exit;
}

public Optional<ContextType> getUpdatedContext() {
public Optional<Context> getUpdatedContext() {
return newContext;
}

Expand All @@ -94,5 +95,4 @@ public boolean equals(Object other) {
public int hashCode() {
return Objects.hash(feedbackToUser, showHelp, exit, newContext);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAY_INDEX);
}

Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAY_INDEX);
}

Person personToEdit = lastShownList.get(index.getZeroBased());
Expand Down
16 changes: 11 additions & 5 deletions src/main/java/seedu/address/logic/commands/ListCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import seedu.address.logic.CommandSubType;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Context;
import seedu.address.model.ContextType;
import seedu.address.model.Model;

/**
Expand Down Expand Up @@ -38,15 +37,22 @@ public ListCommand(CommandSubType type) {
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

// Contextual behaviour
switch (this.type) {
case CONTACT:
model.setContext(Context.newListContactContext());
Context newContactContext = Context.newListContactContext();

model.setContext(newContactContext);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_ENTRIES);
return new CommandResult(String.format(MESSAGE_SUCCESS, "contacts"), ContextType.LIST_CONTACT);

return new CommandResult(String.format(MESSAGE_SUCCESS, "contacts"), newContactContext);
case ACTIVITY:
model.setContext(Context.newListActivityContext());
Context newActivityContext = Context.newListActivityContext();

model.setContext(newActivityContext);
model.updateFilteredActivityList(PREDICATE_SHOW_ALL_ENTRIES);
return new CommandResult(String.format(MESSAGE_SUCCESS, "activities"), ContextType.LIST_ACTIVITY);

return new CommandResult(String.format(MESSAGE_SUCCESS, "activities"), newActivityContext);
default:
throw new CommandException(MESSAGE_UNKNOWN_LIST_TYPE);
}
Expand Down
98 changes: 98 additions & 0 deletions src/main/java/seedu/address/logic/commands/ViewCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ACTIVITY;
import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTACT;

import java.util.List;

import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.CommandSubType;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Context;
import seedu.address.model.Model;
import seedu.address.model.activity.Activity;
import seedu.address.model.person.Person;

/**
* Updates the GUI to list all entries of a specified type to the user.
*/
public class ViewCommand extends Command {

public static final String COMMAND_WORD = "view";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Switches the current view to show the details of a contact or activity, "
+ "identified by their display index (a positive integer) in the respective list.\n"
+ "Parameters: " + PREFIX_CONTACT + "CONTACT_INDEX OR " + PREFIX_ACTIVITY + "ACTIVITY_INDEX\n"
+ "Example: view " + PREFIX_CONTACT + "1";

public static final String MESSAGE_SUCCESS = "Showing the details of %s %s";
public static final String MESSAGE_UNKNOWN_VIEW_TYPE = "View command has unknown type!";

private final Index targetIndex;
private final CommandSubType type;

public ViewCommand(CommandSubType type, Index targetIndex) {
requireAllNonNull(type, targetIndex);
this.type = type;
this.targetIndex = targetIndex;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

// Contextual behaviour
switch (this.type) {
case CONTACT:
List<Person> listedPersons = model.getFilteredPersonList();

if (targetIndex.getOneBased() > listedPersons.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAY_INDEX);
}

Person personToView = listedPersons.get(targetIndex.getZeroBased());
Context newContactContext = new Context(personToView);
model.setContext(newContactContext);

return new CommandResult(String.format(MESSAGE_SUCCESS, "contact", personToView.getName()),
newContactContext);
case ACTIVITY:
List<Activity> listedActivities = model.getFilteredActivityList();

if (targetIndex.getOneBased() > listedActivities.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_ACTIVITY_DISPLAY_INDEX);
}

Activity activityToView = listedActivities.get(targetIndex.getZeroBased());
Context newActivityContext = new Context(activityToView);
model.setContext(newActivityContext);

return new CommandResult(String.format(MESSAGE_SUCCESS, "activity", activityToView.getTitle()),
newActivityContext);
default:
throw new CommandException(MESSAGE_UNKNOWN_VIEW_TYPE);
}
}

@Override
public boolean equals(Object other) {
// short circuit if same object
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof ViewCommand)) {
return false;
}

// state check
ViewCommand v = (ViewCommand) other;
return type.equals(v.type)
&& targetIndex.equals(v.targetIndex);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.InviteCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.parser.exceptions.ParseException;

/**
Expand Down Expand Up @@ -84,6 +85,9 @@ public Command parseCommand(String userInput) throws ParseException {
case DisinviteCommand.COMMAND_WORD:
return new DisinviteCommandParser().parse(arguments);

case ViewCommand.COMMAND_WORD:
return new ViewCommandParser().parse(arguments);

default:
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public ListCommand parse(String args) throws ParseException {
if (argMultimap.getValue(PREFIX_ACTIVITY).isPresent()) {
return new ListCommand(CommandSubType.ACTIVITY);
} else {
assert argMultimap.getValue(PREFIX_CONTACT).isPresent();
return new ListCommand(CommandSubType.CONTACT);
}
}
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/seedu/address/logic/parser/ViewCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ACTIVITY;
import static seedu.address.logic.parser.CliSyntax.PREFIX_CONTACT;

import java.util.stream.Stream;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.CommandSubType;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.parser.exceptions.ParseException;

/**
* Parses input arguments and creates a new {@code ViewCommand} object
*/
public class ViewCommandParser implements Parser<ViewCommand> {

/**
* Parses the given {@code String} of arguments in the context of a {@code ViewCommand}
* and returns a {@code ViewCommand} object for execution.
* @throws ParseException if the user input does not conform to the expected format,
* or has missing compulsory arguments.
*/
public ViewCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_CONTACT, PREFIX_ACTIVITY);

if (!onePrefixPresent(argMultimap, PREFIX_CONTACT, PREFIX_ACTIVITY)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, ViewCommand.MESSAGE_USAGE));
}

CommandSubType subType;
String indexString;

if (argMultimap.getValue(PREFIX_ACTIVITY).isPresent()) {
subType = CommandSubType.ACTIVITY;
indexString = argMultimap.getValue(PREFIX_ACTIVITY).get();
} else {
assert argMultimap.getValue(PREFIX_CONTACT).isPresent();
subType = CommandSubType.CONTACT;
indexString = argMultimap.getValue(PREFIX_CONTACT).get();
}

try {
Index index = ParserUtil.parseIndex(indexString);
return new ViewCommand(subType, index);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ViewCommand.MESSAGE_USAGE), pe);
}
}

/**
* Returns true if exactly one the prefixes contains a non-empty {@code Optional} value in the given
* {@code ArgumentMultimap}.
*/
private static boolean onePrefixPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes)
.filter(prefix -> argumentMultimap.getValue(prefix).isPresent())
.count() == 1;
}
}
10 changes: 8 additions & 2 deletions src/main/java/seedu/address/model/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static java.util.Objects.requireNonNull;

import java.util.Objects;
import java.util.Optional;

import seedu.address.model.activity.Activity;
Expand All @@ -18,7 +19,7 @@ public class Context {
/**
* Default constructor where context type is MAIN.
*/
Context() {
public Context() {
this.object = Optional.empty();
this.type = ContextType.MAIN;
}
Expand All @@ -40,7 +41,7 @@ public Context(Activity activity) {
/**
* Constructor for a VIEW_CONTACT context.
*/
Context(Person person) {
public Context(Person person) {
requireNonNull(person);
object = Optional.ofNullable(person);
type = ContextType.VIEW_CONTACT;
Expand Down Expand Up @@ -72,6 +73,11 @@ public Optional<Person> getContact() {
return object.filter(x -> type == ContextType.VIEW_CONTACT).map(x->(Person) x);
}

@Override
public int hashCode() {
return Objects.hash(type, object);
}

@Override
public boolean equals(Object other) {
if (this == other) {
Expand Down
Loading

0 comments on commit 584781e

Please sign in to comment.