Skip to content

Commit

Permalink
Merge pull request #114 from aexolate/branch-sort-command
Browse files Browse the repository at this point in the history
Add Sort Command
  • Loading branch information
Weiennn authored Oct 23, 2023
2 parents 425374c + 788706d commit f3e83fa
Show file tree
Hide file tree
Showing 36 changed files with 571 additions and 48 deletions.
22 changes: 22 additions & 0 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,28 @@ no employee will be deleted or modified.
Examples:
* `delete id/A1234567B` deletes the employee with the ID `A1234567B` if such employee exists.


### Sort displayed entries : `sort`

Sorts the currently displayed list in EmployeeManager based on the specified prefix in ascending order.

Format: `sort [i/] [d/] [e/] [s/] [r/] [n/] [p/]`

* The prefix specifies the attribute to be sorted with.
* Exactly one of the prefix must be specified.
* Attributes are sorted by lexicographical order except for salary which
is simply by numerical order.

Examples:
* `sort i/` sorts the displayed list in ascending ID.
* `sort d/` sorts the displayed list in ascending department.
* `sort e/` sorts the displayed list in ascending email.
* `sort s/` sorts the displayed list in ascending salary.
* `sort r/` sorts the displayed list in ascending role.
* `sort n/` sorts the displayed list in ascending name.
* `sort p/` sorts the displayed list in ascending phone.


### Clearing all entries : `clear`

Clears the current list of entries from EmployeeManager.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public interface Logic {
*/
ReadOnlyAddressBook getAddressBook();

/** Returns an unmodifiable view of the filtered list of persons */
ObservableList<Person> getFilteredPersonList();
/** Returns an unmodifiable view of the sorted and filtered list of persons */
ObservableList<Person> getSortedFilteredPersonList();

/**
* Returns the user prefs' address book file path.
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ public ReadOnlyAddressBook getAddressBook() {
}

@Override
public ObservableList<Person> getFilteredPersonList() {
return model.getFilteredPersonList();
public ObservableList<Person> getSortedFilteredPersonList() {
return model.getSortedFilteredPersonList();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class ClearCommand extends Command {
@Override
public CommandResult execute(Model model) {
requireNonNull(model);
ArrayList<Person> copyList = new ArrayList<>(model.getFilteredPersonList());
ArrayList<Person> copyList = new ArrayList<>(model.getSortedFilteredPersonList());
copyList.forEach(model::deletePerson);

return new CommandResult(MESSAGE_SUCCESS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public DeleteCommand(Index targetIndex) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
List<Person> lastShownList = model.getSortedFilteredPersonList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
List<Person> lastShownList = model.getSortedFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredPersonList(predicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size()));
String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getSortedFilteredPersonList().size()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public IncrementCommand(Increment increment) {
@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
List<Person> lastShownList = model.getSortedFilteredPersonList();
checkValidIncrement(lastShownList);

for (Person personToEdit : lastShownList) {
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/seedu/address/logic/commands/SortCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DEPARTMENT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ID;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SALARY;

import java.util.Comparator;

import seedu.address.model.Model;
import seedu.address.model.person.Person;

/**
* Sorts the list that is displayed to the user.
*/
public class SortCommand extends Command {

public static final String COMMAND_WORD = "sort";

public static final String MESSAGE_SUCCESS = "List successfully sorted.";
public static final String MESSAGE_MULTIPLE_PREFIXES = "Sorting by multiple prefixes is not supported.";

public static final String MESSAGE_USAGE = "Sorts the list displayed based on the prefix provided."
+ "\n" + "Parameters: "
+ "[" + PREFIX_ID + "] " + "or " + "[" + PREFIX_DEPARTMENT + "] " + "or " + "[" + PREFIX_EMAIL + "] "
+ "or " + "[" + PREFIX_SALARY + "] " + "or " + "[" + PREFIX_ROLE + "] "
+ "or " + "[" + PREFIX_NAME + "] " + "or " + "[" + PREFIX_PHONE + "] "
+ "\n"

+ "Examples: " + "\n" + COMMAND_WORD + " " + PREFIX_ID
+ "\n" + COMMAND_WORD + " " + PREFIX_NAME;

private final Comparator<Person> comparator;

public SortCommand(Comparator<Person> comparator) {
this.comparator = comparator;
}

@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateSortedPersonList(comparator);
return new CommandResult(MESSAGE_SUCCESS);
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

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

SortCommand otherFindCommand = (SortCommand) other;
return comparator.equals(otherFindCommand.comparator);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.IncrementCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.parser.exceptions.ParseException;

/**
Expand Down Expand Up @@ -75,6 +76,9 @@ public Command parseCommand(String userInput) throws ParseException {
case ListCommand.COMMAND_WORD:
return new ListCommand();

case SortCommand.COMMAND_WORD:
return new SortCommandParser().parse(arguments);

case ExitCommand.COMMAND_WORD:
return new ExitCommand();

Expand Down
16 changes: 16 additions & 0 deletions src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public List<String> getAllValues(Prefix prefix) {
return new ArrayList<>(argMultimap.get(prefix));
}

/**
* Returns whether {@code prefix} exists inside the map.
*/
public boolean hasPrefix(Prefix prefix) {
return argMultimap.containsKey(prefix);
}

/**
* Returns the preamble (text before the first valid prefix). Trims any leading/trailing spaces.
*/
Expand All @@ -75,4 +82,13 @@ public void verifyNoDuplicatePrefixesFor(Prefix... prefixes) throws ParseExcepti
throw new ParseException(Messages.getErrorMessageForDuplicatePrefixes(duplicatedPrefixes));
}
}

/**
* Returns the total number of non-empty prefixes in the argMultimap.
*/
public int getPrefixCount() {
return (int) argMultimap.keySet().stream()
.filter(prefix -> !prefix.getPrefix().isBlank())
.count();
}
}
74 changes: 74 additions & 0 deletions src/main/java/seedu/address/logic/parser/SortCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_DEPARTMENT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ID;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ROLE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SALARY;

import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.PersonComparators;


/**
* Parses input arguments and creates a new SortCommand object
*/
public class SortCommandParser implements Parser<SortCommand> {

private static final int EXPECTED_PREFIX_COUNT = 1;

/**
* Parses the given {@code String} of arguments in the context of the SortCommand
* and returns a SortCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public SortCommand parse(String args) throws ParseException {
requireNonNull(args);
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_ID, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_DEPARTMENT,
PREFIX_ROLE, PREFIX_SALARY);

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_ID, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_DEPARTMENT,
PREFIX_ROLE, PREFIX_SALARY);

if (argMultimap.getPrefixCount() != EXPECTED_PREFIX_COUNT) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
}

if (argMultimap.hasPrefix(PREFIX_ID)) {
return new SortCommand(PersonComparators.COMPARATOR_ID);
}

if (argMultimap.hasPrefix(PREFIX_NAME)) {
return new SortCommand(PersonComparators.COMPARATOR_NAME);
}

if (argMultimap.hasPrefix(PREFIX_DEPARTMENT)) {
return new SortCommand(PersonComparators.COMPARATOR_DEPARTMENT);
}

if (argMultimap.hasPrefix(PREFIX_EMAIL)) {
return new SortCommand(PersonComparators.COMPARATOR_EMAIL);
}

if (argMultimap.hasPrefix(PREFIX_ROLE)) {
return new SortCommand(PersonComparators.COMPARATOR_ROLE);
}

if (argMultimap.hasPrefix(PREFIX_SALARY)) {
return new SortCommand(PersonComparators.COMPARATOR_SALARY);
}

if (argMultimap.hasPrefix(PREFIX_PHONE)) {
return new SortCommand(PersonComparators.COMPARATOR_PHONE);
}

throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
}

}
9 changes: 8 additions & 1 deletion src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.address.model;

import java.nio.file.Path;
import java.util.Comparator;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
Expand Down Expand Up @@ -77,11 +78,17 @@ public interface Model {
void setPerson(Person target, Person editedPerson);

/** Returns an unmodifiable view of the filtered person list */
ObservableList<Person> getFilteredPersonList();
ObservableList<Person> getSortedFilteredPersonList();

/**
* Updates the filter of the filtered person list to filter by the given {@code predicate}.
* @throws NullPointerException if {@code predicate} is null.
*/
void updateFilteredPersonList(Predicate<Person> predicate);

/**
* Sorts the filtered person list based on the given {@code comparator}.
* @throws NullPointerException if {@code comparator} is null.
*/
void updateSortedPersonList(Comparator<Person> comparator);
}
14 changes: 12 additions & 2 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.nio.file.Path;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.logging.Logger;

import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.person.Person;
Expand All @@ -21,6 +23,7 @@ public class ModelManager implements Model {

private final AddressBook addressBook;
private final UserPrefs userPrefs;
private final SortedList<Person> sortedPersons;
private final FilteredList<Person> filteredPersons;

/**
Expand All @@ -34,6 +37,7 @@ public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs
this.addressBook = new AddressBook(addressBook);
this.userPrefs = new UserPrefs(userPrefs);
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
sortedPersons = new SortedList<>(filteredPersons);
}

public ModelManager() {
Expand Down Expand Up @@ -118,8 +122,8 @@ public void setPerson(Person target, Person editedPerson) {
* {@code versionedAddressBook}
*/
@Override
public ObservableList<Person> getFilteredPersonList() {
return filteredPersons;
public ObservableList<Person> getSortedFilteredPersonList() {
return sortedPersons;
}

@Override
Expand All @@ -128,6 +132,12 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
filteredPersons.setPredicate(predicate);
}

@Override
public void updateSortedPersonList(Comparator<Person> comparator) {
requireNonNull(comparator);
sortedPersons.setComparator(comparator);
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/seedu/address/model/person/Department.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Represents a Employee's Department in EmployeeManager.
* Guarantees: immutable; is valid as declared in {@link #isValidDepartment(String)}
*/
public class Department {
public class Department implements Comparable<Department> {
public static final String MESSAGE_CONSTRAINTS =
"Department names should only contain alphanumeric characters and spaces, and it should not be blank";

Expand Down Expand Up @@ -61,4 +61,9 @@ public boolean equals(Object other) {
public int hashCode() {
return value.hashCode();
}

@Override
public int compareTo(Department other) {
return this.value.compareTo(other.value);
}
}
Loading

0 comments on commit f3e83fa

Please sign in to comment.