From 5f1cdac83d5e5fc2ba803fbd320064dd573ca247 Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Wed, 17 Mar 2021 20:26:43 +0800 Subject: [PATCH 01/19] added delete all person from group --- .../DeleteAllPersonFromGroupCommand.java | 52 +++++++++++++++++++ .../logic/parser/AddressBookParser.java | 4 ++ ...DeleteAllPersonFromGroupCommandParser.java | 43 +++++++++++++++ .../java/seedu/address/model/AddressBook.java | 18 +++++++ src/main/java/seedu/address/model/Model.java | 4 ++ .../seedu/address/model/ModelManager.java | 13 +++++ .../seedu/address/model/group/GroupList.java | 8 +-- .../java/seedu/address/ui/MainWindow.java | 2 +- .../typicalPersonsAddressBook.json | 7 +++ 9 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java new file mode 100644 index 00000000..df6379e8 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java @@ -0,0 +1,52 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GROUP; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; +import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; +import static seedu.address.model.Model.predicateShowAllPersonsInGroup; + +import java.util.ArrayList; + +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.group.Group; +import seedu.address.model.person.Person; + +public class DeleteAllPersonFromGroupCommand extends Command { + + public static final String COMMAND_WORD = "deletepsngrp"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": delete all person in a group. " + + "Parameters: " + PREFIX_GROUP + "GROUP NAME "; + + public static final String MESSAGE_SUCCESS = "all Person has been deleted from Group %1$s. "; + public static final String MESSAGE_NO_EXIST_GROUP = "The Group doesn't exists in the address book"; + + private final Group group; + + public DeleteAllPersonFromGroupCommand(Group group) { + requireNonNull(group); + this.group = group; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (!model.hasGroup(this.group)) { + throw new CommandException(MESSAGE_NO_EXIST_GROUP); + } + + // select all people in this.group + ArrayList personInGroup = model.getPersonListInThisGroup(this.group); + // remove this.group from each of them + for(int i = 0; i < personInGroup.size(); i++) { + Person person = personInGroup.get(i); + model.unAssignPersonToGroup(person); + } + + model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS); + return new CommandResult(String.format(MESSAGE_SUCCESS, group)); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index e50dd355..8dd6a918 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -11,6 +11,7 @@ import seedu.address.logic.commands.AssignPersonToGroupCommand; import seedu.address.logic.commands.ClearCommand; import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.DeleteAllPersonFromGroupCommand; import seedu.address.logic.commands.DeleteCommand; import seedu.address.logic.commands.DeleteGroupCommand; import seedu.address.logic.commands.EditCommand; @@ -89,6 +90,9 @@ public Command parseCommand(String userInput) throws ParseException { case HelpCommand.COMMAND_WORD: return new HelpCommand(); + case DeleteAllPersonFromGroupCommand.COMMAND_WORD: + return new DeleteAllPersonFromGroupCommandParser().parse(arguments); // Delete everyone from a group + default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); } diff --git a/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java new file mode 100644 index 00000000..dee63bc5 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java @@ -0,0 +1,43 @@ +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_GROUP; +import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; + +import java.util.stream.Stream; + +import seedu.address.logic.commands.AddGroupCommand; +import seedu.address.logic.commands.AssignPersonToGroupCommand; +import seedu.address.logic.commands.DeleteAllPersonFromGroupCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.group.Group; +import seedu.address.model.person.Name; + +public class DeleteAllPersonFromGroupCommandParser { + public DeleteAllPersonFromGroupCommand parse(String args) throws ParseException { + requireNonNull(args); + + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_GROUP); + + if (!arePrefixesPresent(argMultimap, PREFIX_GROUP) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + DeleteAllPersonFromGroupCommand.MESSAGE_USAGE)); + } + + Group group = ParserUtil.parseGroup(argMultimap.getValue(PREFIX_GROUP).get()); + + return new DeleteAllPersonFromGroupCommand(group); + + } + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } +} diff --git a/src/main/java/seedu/address/model/AddressBook.java b/src/main/java/seedu/address/model/AddressBook.java index e35f3e9c..5f82f172 100644 --- a/src/main/java/seedu/address/model/AddressBook.java +++ b/src/main/java/seedu/address/model/AddressBook.java @@ -2,9 +2,11 @@ import static java.util.Objects.requireNonNull; +import java.util.ArrayList; import java.util.List; import javafx.collections.ObservableList; +import seedu.address.model.group.Group; import seedu.address.model.person.Name; import seedu.address.model.person.Person; import seedu.address.model.person.UniquePersonList; @@ -101,6 +103,22 @@ public Person getPerson(Name name) { return null; } + /** + * Get the list of person that is in the given Group + */ + public ArrayList getPersonListInThisGroup(Group group) { + requireNonNull(group); + ArrayList personArrayList = new ArrayList(); + + for (Person person : persons) { + if (person.getGroup().equals(group)) { + personArrayList.add(person); + } + } + + return personArrayList; + } + /** * Removes {@code key} from this {@code AddressBook}. * {@code key} must exist in the address book. diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index e38a001b..8f643ea6 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -1,6 +1,7 @@ package seedu.address.model; import java.nio.file.Path; +import java.util.ArrayList; import java.util.function.Predicate; import javafx.collections.ObservableList; @@ -124,4 +125,7 @@ public static Predicate predicateShowAllPersonsInGroup(Group group) { */ void addGroup(Group toAdd); + ArrayList getPersonListInThisGroup(Group group); + + void unAssignPersonToGroup(Person person); } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 165a628d..aaae7af6 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -4,6 +4,7 @@ import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; import java.nio.file.Path; +import java.util.ArrayList; import java.util.function.Predicate; import java.util.logging.Logger; @@ -113,11 +114,23 @@ public Person getPerson(Name personName) { return addressBook.getPerson(personName); } + @Override + public ArrayList getPersonListInThisGroup(Group group) { + return addressBook.getPersonListInThisGroup(group); + } + @Override public void assignPersonToGroup(Group group, Person person) { person.setGroup(group); } + + public void unAssignPersonToGroup(Person person) { + Group emptyGroup = new Group(); + emptyGroup.setGroupName("N/A"); + person.setGroup(emptyGroup); + } + @Override public void setPerson(Person target, Person editedPerson) { requireAllNonNull(target, editedPerson); diff --git a/src/main/java/seedu/address/model/group/GroupList.java b/src/main/java/seedu/address/model/group/GroupList.java index 1198b30b..db96de8f 100644 --- a/src/main/java/seedu/address/model/group/GroupList.java +++ b/src/main/java/seedu/address/model/group/GroupList.java @@ -54,9 +54,11 @@ public static String listGroups () { StringBuffer output = new StringBuffer(); for (int i = 0; i < listOfGroup.size(); i++) { - output.append(i + 1); - output.append(". " + listOfGroup.get(i).toString()); - output.append(System.lineSeparator()); + if(!listOfGroup.get(i).toString().equals("N/A")) { + output.append(i + 1); + output.append(". " + listOfGroup.get(i).toString()); + output.append(System.lineSeparator()); + } } return output.toString(); } diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index 9106c3aa..cbf5cc5c 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -120,7 +120,7 @@ void fillInnerParts() { statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); CommandBox commandBox = new CommandBox(this::executeCommand); - commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); + commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); // could the selection of all person from the group be selected and displayed here? } /** diff --git a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json index f10eddee..0b1d163f 100644 --- a/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/typicalPersonsAddressBook.json @@ -6,41 +6,48 @@ "email" : "alice@example.com", "address" : "123, Jurong West Ave 6, #08-111", "tagged" : [ "friends" ] + }, { "name" : "Benson Meier", "phone" : "98765432", "email" : "johnd@example.com", "address" : "311, Clementi Ave 2, #02-25", "tagged" : [ "owesMoney", "friends" ] + }, { "name" : "Carl Kurz", "phone" : "95352563", "email" : "heinz@example.com", "address" : "wall street", "tagged" : [ ] + }, { "name" : "Daniel Meier", "phone" : "87652533", "email" : "cornelia@example.com", "address" : "10th street", "tagged" : [ "friends" ] + }, { "name" : "Elle Meyer", "phone" : "9482224", "email" : "werner@example.com", "address" : "michegan ave", "tagged" : [ ] + }, { "name" : "Fiona Kunz", "phone" : "9482427", "email" : "lydia@example.com", "address" : "little tokyo", "tagged" : [ ] + }, { "name" : "George Best", "phone" : "9482442", "email" : "anna@example.com", "address" : "4th street", "tagged" : [ ] + } ] } From 38e7840004d0bcceba23db4375fba88f85ea50b0 Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Thu, 18 Mar 2021 19:42:32 +0800 Subject: [PATCH 02/19] fixed checkstyle --- .../commands/DeleteAllPersonFromGroupCommand.java | 10 +++++++--- .../parser/DeleteAllPersonFromGroupCommandParser.java | 10 ++++++---- src/main/java/seedu/address/model/ModelManager.java | 5 ++++- src/main/java/seedu/address/model/group/GroupList.java | 2 +- src/main/java/seedu/address/ui/MainWindow.java | 2 +- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java index df6379e8..d0b45fee 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java @@ -2,9 +2,7 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_GROUP; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS; -import static seedu.address.model.Model.predicateShowAllPersonsInGroup; import java.util.ArrayList; @@ -30,6 +28,12 @@ public DeleteAllPersonFromGroupCommand(Group group) { this.group = group; } + /** + * Run the process of deleting all people from the group + * @param model {@code Model} which the command should operate on. + * @return Message success + * @throws CommandException if group does not exists + */ @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); @@ -41,7 +45,7 @@ public CommandResult execute(Model model) throws CommandException { // select all people in this.group ArrayList personInGroup = model.getPersonListInThisGroup(this.group); // remove this.group from each of them - for(int i = 0; i < personInGroup.size(); i++) { + for (int i = 0; i < personInGroup.size(); i++) { Person person = personInGroup.get(i); model.unAssignPersonToGroup(person); } diff --git a/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java b/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java index dee63bc5..c980ebf8 100644 --- a/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/DeleteAllPersonFromGroupCommandParser.java @@ -3,18 +3,20 @@ 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_GROUP; -import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import java.util.stream.Stream; -import seedu.address.logic.commands.AddGroupCommand; -import seedu.address.logic.commands.AssignPersonToGroupCommand; import seedu.address.logic.commands.DeleteAllPersonFromGroupCommand; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.group.Group; -import seedu.address.model.person.Name; public class DeleteAllPersonFromGroupCommandParser { + /** + * Parse the value inputted into the deletepsngrp command + * @param args the group to delete + * @return the group + * @throws ParseException if group is not a valid prefix + */ public DeleteAllPersonFromGroupCommand parse(String args) throws ParseException { requireNonNull(args); diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index aaae7af6..dd6d4849 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -124,7 +124,10 @@ public void assignPersonToGroup(Group group, Person person) { person.setGroup(group); } - + /** + * remove a person from group, replace group with "N/A" indicator + * @param person to remove group from + */ public void unAssignPersonToGroup(Person person) { Group emptyGroup = new Group(); emptyGroup.setGroupName("N/A"); diff --git a/src/main/java/seedu/address/model/group/GroupList.java b/src/main/java/seedu/address/model/group/GroupList.java index db96de8f..7bb93f28 100644 --- a/src/main/java/seedu/address/model/group/GroupList.java +++ b/src/main/java/seedu/address/model/group/GroupList.java @@ -54,7 +54,7 @@ public static String listGroups () { StringBuffer output = new StringBuffer(); for (int i = 0; i < listOfGroup.size(); i++) { - if(!listOfGroup.get(i).toString().equals("N/A")) { + if (!listOfGroup.get(i).toString().equals("N/A")) { output.append(i + 1); output.append(". " + listOfGroup.get(i).toString()); output.append(System.lineSeparator()); diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index cbf5cc5c..d8a68fca 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -120,7 +120,7 @@ void fillInnerParts() { statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); CommandBox commandBox = new CommandBox(this::executeCommand); - commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); // could the selection of all person from the group be selected and displayed here? + commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } /** From 81c9905ad04cae9564c532933e619c9adf875c6f Mon Sep 17 00:00:00 2001 From: Tay Jun Wen <43071400+tototto@users.noreply.github.com> Date: Thu, 18 Mar 2021 19:51:21 +0800 Subject: [PATCH 03/19] Update MainWindow.java --- src/main/java/seedu/address/ui/MainWindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index d8a68fca..9106c3aa 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -120,7 +120,7 @@ void fillInnerParts() { statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); CommandBox commandBox = new CommandBox(this::executeCommand); - commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); + commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } /** From a091d7d610e30a6cfbe4cc4b88cfddc92b55fb27 Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Thu, 18 Mar 2021 19:54:15 +0800 Subject: [PATCH 04/19] added javadocs to fix checkstyle error --- .../logic/commands/DeleteAllPersonFromGroupCommand.java | 4 ++++ src/main/java/seedu/address/ui/MainWindow.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java index d0b45fee..3ebb254f 100644 --- a/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/DeleteAllPersonFromGroupCommand.java @@ -23,6 +23,10 @@ public class DeleteAllPersonFromGroupCommand extends Command { private final Group group; + /** + * constructor to set the group + * @param group + */ public DeleteAllPersonFromGroupCommand(Group group) { requireNonNull(group); this.group = group; diff --git a/src/main/java/seedu/address/ui/MainWindow.java b/src/main/java/seedu/address/ui/MainWindow.java index d8a68fca..9106c3aa 100644 --- a/src/main/java/seedu/address/ui/MainWindow.java +++ b/src/main/java/seedu/address/ui/MainWindow.java @@ -120,7 +120,7 @@ void fillInnerParts() { statusbarPlaceholder.getChildren().add(statusBarFooter.getRoot()); CommandBox commandBox = new CommandBox(this::executeCommand); - commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); + commandBoxPlaceholder.getChildren().add(commandBox.getRoot()); } /** From c73785620c1e35ef7d5a46a73da02587c8890dff Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Thu, 18 Mar 2021 20:03:26 +0800 Subject: [PATCH 05/19] fixed testcase error --- .../seedu/address/logic/commands/AddCommandTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index 4d1b13ca..37b69f58 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -174,6 +174,16 @@ public boolean hasGroup(Group toAdd) { public void addGroup(Group toAdd) { return; } + + @Override + public ArrayList getPersonListInThisGroup(Group group) { + return null; + } + + @Override + public void unAssignPersonToGroup(Person person) { + + } } /** From 014254d0360e84ea88b47df50af39b222c862aa0 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Fri, 19 Mar 2021 14:46:22 +0800 Subject: [PATCH 06/19] commit 1st draft of RenameGroupCommand --- .../logic/commands/RenameGroupCommand.java | 48 +++++++++++++++ .../logic/parser/AddressBookParser.java | 18 ++---- .../parser/RenameGroupCommandParser.java | 59 +++++++++++++++++++ src/main/java/seedu/address/model/Model.java | 17 ++++++ .../seedu/address/model/ModelManager.java | 15 +++++ .../seedu/address/model/group/GroupList.java | 4 ++ 6 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 src/main/java/seedu/address/logic/commands/RenameGroupCommand.java create mode 100644 src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java diff --git a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java new file mode 100644 index 00000000..d5b02228 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java @@ -0,0 +1,48 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GROUP; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.group.Group; +import seedu.address.model.group.GroupList; + +public class RenameGroupCommand extends Command { + public static final String COMMAND_WORD = "rename"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + + ": Rename the group identified by the index number used in the displayed group list and a specified " + + "new name.\n" + + "Parameters: INDEX (must be a positive integer) " + PREFIX_GROUP + " GROUP_NAME\n" + + "Example: " + COMMAND_WORD + " 1" + PREFIX_GROUP + "NEW_GROUP_NAME"; + + public static final String MESSAGE_SUCCESS = "Group index %1$d rename successfully: %2$s"; + public static final String MESSAGE_INVALID_INDEX = "The index specified is invalid."; + + private final Index targetIndex; + private final Group group; + + /** + * @param targetIndex the target specified index + * @param group the renamed group name + */ + public RenameGroupCommand(Index targetIndex, Group group) { + this.targetIndex = targetIndex; + this.group = group; + } + + @Override + public CommandResult execute(Model model) throws CommandException { + requireNonNull(model); + + if (targetIndex.getOneBased() <= 0 || targetIndex.getOneBased() > model.getGroupSize()) { + throw new CommandException(MESSAGE_INVALID_INDEX); + } + + model.renameGroup(targetIndex.getOneBased(), group.toString()); + return new CommandResult(String.format(MESSAGE_SUCCESS, targetIndex.getOneBased(), group.toString())); + } +} diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index e50dd355..56d8258e 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -6,20 +6,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.address.logic.commands.AddCommand; -import seedu.address.logic.commands.AddGroupCommand; -import seedu.address.logic.commands.AssignPersonToGroupCommand; -import seedu.address.logic.commands.ClearCommand; -import seedu.address.logic.commands.Command; -import seedu.address.logic.commands.DeleteCommand; -import seedu.address.logic.commands.DeleteGroupCommand; -import seedu.address.logic.commands.EditCommand; -import seedu.address.logic.commands.ExitCommand; -import seedu.address.logic.commands.FindCommand; -import seedu.address.logic.commands.HelpCommand; -import seedu.address.logic.commands.ListAllFromGroupCommand; -import seedu.address.logic.commands.ListCommand; -import seedu.address.logic.commands.ShowCommand; +import seedu.address.logic.commands.*; import seedu.address.logic.parser.exceptions.ParseException; /** @@ -62,6 +49,9 @@ public Command parseCommand(String userInput) throws ParseException { case DeleteGroupCommand.COMMAND_WORD: return new DeleteGroupCommandParser().parse(arguments); + case RenameGroupCommand.COMMAND_WORD: + return new RenameGroupCommandParser().parse(arguments); + case EditCommand.COMMAND_WORD: return new EditCommandParser().parse(arguments); diff --git a/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java b/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java new file mode 100644 index 00000000..a56747b2 --- /dev/null +++ b/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java @@ -0,0 +1,59 @@ +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_GROUP; + +import java.util.stream.Stream; + +import seedu.address.commons.core.index.Index; +import seedu.address.logic.commands.RenameGroupCommand; +import seedu.address.logic.parser.exceptions.ParseException; +import seedu.address.model.group.Group; + + +public class RenameGroupCommandParser { + /** + * return an RenameGroupCommand command object that contains the value of user inputted index + * and group name + * @param args contains index and group name + * @return an RenameGroupCommand command object + * @throws ParseException if parsing of person or group value fails + */ + public RenameGroupCommand parse(String args) throws ParseException { + requireNonNull(args); + + ArgumentMultimap argMultimap = + ArgumentTokenizer.tokenize(args, PREFIX_GROUP); + + Index index; + + try { + index = ParserUtil.parseIndex(argMultimap.getPreamble()); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, RenameGroupCommand.MESSAGE_USAGE), pe); + } + + if (!arePrefixesPresent(argMultimap, PREFIX_GROUP) + || !argMultimap.getPreamble().isEmpty()) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + RenameGroupCommand.MESSAGE_USAGE)); + } + + Group group = ParserUtil.parseGroup(argMultimap.getValue(PREFIX_GROUP).get()); + + return new RenameGroupCommand(index, group); + + } + + + /** + * Returns true if none of the prefixes contains empty {@code Optional} values in the given + * {@code ArgumentMultimap}. + */ + private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) { + return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent()); + } + +} diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index e38a001b..928c4a03 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -124,4 +124,21 @@ public static Predicate predicateShowAllPersonsInGroup(Group group) { */ void addGroup(Group toAdd); + /** + * return the group at the index i in the group list. + * {@code i} an int index . + */ + Group getGroupByIndex(int i); + + /** + * return the group at the index i in the group list. + * {@code i} an int index . + */ + void renameGroup(int i, String name); + + /** + * get the group size of group list. + */ + int getGroupSize(); + } diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index 165a628d..bef4b434 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -164,6 +164,21 @@ public void addGroup(Group toAdd) { GroupList.addGroup(toAdd); } + @Override + public Group getGroupByIndex(int i) { + return GroupList.getGroup(i); + } + + @Override + public int getGroupSize() { + return GroupList.getGroupListSize(); + } + + @Override + public void renameGroup(int i, String name) { + GroupList.getGroup(i).setGroupName(name); + } + @Override public boolean equals(Object obj) { // short circuit if same object diff --git a/src/main/java/seedu/address/model/group/GroupList.java b/src/main/java/seedu/address/model/group/GroupList.java index 3adc90aa..79f4229a 100644 --- a/src/main/java/seedu/address/model/group/GroupList.java +++ b/src/main/java/seedu/address/model/group/GroupList.java @@ -73,4 +73,8 @@ public static String listGroups () { return output.toString(); } + public static int getGroupListSize() { + return listOfGroup.size(); + } + } From efe4d407f6570d7bb74a38f9df9eadfc5f950d94 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Fri, 19 Mar 2021 15:04:31 +0800 Subject: [PATCH 07/19] Refine RenameGroupCommand 1. Refine RenameGroupCommand 2. update user guide --- docs/UserGuide.md | 4 ++-- .../logic/commands/RenameGroupCommand.java | 2 -- .../address/logic/parser/AddressBookParser.java | 16 +++++++++++++++- .../logic/parser/RenameGroupCommandParser.java | 3 +-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 81b289e3..67f20011 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -201,7 +201,7 @@ Examples: Rename an existing group to another name. -Format: `rename INDEX [n/NAME]` +Format: `rename INDEX [g/NAME]` * Rename the group at the specified INDEX * The index refers to the index number shown in the displayed group list. @@ -209,7 +209,7 @@ Format: `rename INDEX [n/NAME]` * Existing values will be updated to the input values. Examples: -* `rename 1 n/PERFORMANCE ` Rename the group with index 1 into PERFORMANCE. +* `rename 1 g/PERFORMANCE ` Rename the group with index 1 into PERFORMANCE. ### List all persons in a group: `list -g [group name]` diff --git a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java index d5b02228..3b8e147e 100644 --- a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java @@ -3,12 +3,10 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_GROUP; -import seedu.address.commons.core.Messages; import seedu.address.commons.core.index.Index; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.model.Model; import seedu.address.model.group.Group; -import seedu.address.model.group.GroupList; public class RenameGroupCommand extends Command { public static final String COMMAND_WORD = "rename"; diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/AddressBookParser.java index 56d8258e..b150ecda 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/AddressBookParser.java @@ -6,7 +6,21 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import seedu.address.logic.commands.*; +import seedu.address.logic.commands.AddCommand; +import seedu.address.logic.commands.AddGroupCommand; +import seedu.address.logic.commands.AssignPersonToGroupCommand; +import seedu.address.logic.commands.ClearCommand; +import seedu.address.logic.commands.Command; +import seedu.address.logic.commands.DeleteCommand; +import seedu.address.logic.commands.DeleteGroupCommand; +import seedu.address.logic.commands.EditCommand; +import seedu.address.logic.commands.ExitCommand; +import seedu.address.logic.commands.FindCommand; +import seedu.address.logic.commands.HelpCommand; +import seedu.address.logic.commands.ListAllFromGroupCommand; +import seedu.address.logic.commands.ListCommand; +import seedu.address.logic.commands.RenameGroupCommand; +import seedu.address.logic.commands.ShowCommand; import seedu.address.logic.parser.exceptions.ParseException; /** diff --git a/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java b/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java index a56747b2..bdef6162 100644 --- a/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java +++ b/src/main/java/seedu/address/logic/parser/RenameGroupCommandParser.java @@ -35,8 +35,7 @@ public RenameGroupCommand parse(String args) throws ParseException { String.format(MESSAGE_INVALID_COMMAND_FORMAT, RenameGroupCommand.MESSAGE_USAGE), pe); } - if (!arePrefixesPresent(argMultimap, PREFIX_GROUP) - || !argMultimap.getPreamble().isEmpty()) { + if (!arePrefixesPresent(argMultimap, PREFIX_GROUP)) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RenameGroupCommand.MESSAGE_USAGE)); } From c0bbc11e93df9fb2d497478754c655d1f54ad9eb Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Fri, 19 Mar 2021 20:20:47 +0800 Subject: [PATCH 08/19] fixed issues with Data and merge conflit with team --- data/addressbook.json | 27 ++++++++++++------- .../seedu/address/model/group/GroupList.java | 4 +-- .../invalidAndValidPersonAddressBook.json | 6 ++--- .../invalidPersonAddressBook.json | 4 +-- .../duplicatePersonAddressBook.json | 6 ++--- .../invalidPersonAddressBook.json | 4 +-- 6 files changed, 29 insertions(+), 22 deletions(-) diff --git a/data/addressbook.json b/data/addressbook.json index d51464b4..7aa0eded 100644 --- a/data/addressbook.json +++ b/data/addressbook.json @@ -5,57 +5,64 @@ "email" : "alexyeoh@example.com", "address" : "Blk 30 Lorong 3 Serangoon Gardens, #07-18", "tagged" : [ "friends" ], - "group" : "NA" + "group" : "N/A" }, { "name" : "Bernice Yu", "phone" : "99272758", "email" : "berniceyu@example.com", "address" : "Blk 30 Lorong 3 Serangoon Gardens, #07-18", "tagged" : [ "colleagues", "friends" ], - "group" : "NIL" + "group" : "N/A" }, { "name" : "Charlotte Oliveiro", "phone" : "93210283", "email" : "charlotte@example.com", "address" : "Blk 11 Ang Mo Kio Street 74, #11-04", "tagged" : [ "neighbours" ], - "group" : "NIL" + "group" : "N/A" }, { "name" : "David Li", "phone" : "91031282", "email" : "lidavid@example.com", "address" : "Blk 436 Serangoon Gardens Street 26, #16-43", "tagged" : [ "family" ], - "group" : "NA" + "group" : "N/A" }, { "name" : "Irfan Ibrahim", "phone" : "92492021", "email" : "irfan@example.com", "address" : "Blk 47 Tampines Street 20, #17-35", "tagged" : [ "classmates" ], - "group" : "NA" + "group" : "N/A" }, { "name" : "Roy Balakrishnan", "phone" : "92624417", "email" : "royb@example.com", "address" : "Blk 45 Aljunied Street 85, #11-31", "tagged" : [ "colleagues" ], - "group" : "NIL" + "group" : "N/A" }, { "name" : "John Doe", "phone" : "98765432", "email" : "johnd@example.com", "address" : "John street, block 123, #01-01", "tagged" : [ ], - "group" : "NA" + "group" : "N/A" + }, { + "name" : "John Poh", + "phone" : "98765432", + "email" : "johnd@example.com", + "address" : "John street, block 123, #01-01", + "tagged" : [ ], + "group" : "N/A" } ], "groups" : [ { - "group" : "NA" + "group" : "N/A" }, { "group" : "A" }, { "group" : "B" }, { - "group" : "NIL" + "group" : "C" } ] -} +} \ No newline at end of file diff --git a/src/main/java/seedu/address/model/group/GroupList.java b/src/main/java/seedu/address/model/group/GroupList.java index bf760982..87df077d 100644 --- a/src/main/java/seedu/address/model/group/GroupList.java +++ b/src/main/java/seedu/address/model/group/GroupList.java @@ -8,7 +8,7 @@ public class GroupList { GroupList() { Group defaultGroup = new Group(); - defaultGroup.setGroupName("NA"); + defaultGroup.setGroupName("N/A"); addGroup(defaultGroup); } @@ -67,7 +67,7 @@ public static String listGroups () { for (int i = 0; i < listOfGroup.size(); i++) { if (!listOfGroup.get(i).toString().equals("N/A")) { - output.append(i + 1); + output.append(i); output.append(". " + listOfGroup.get(i).toString()); output.append(System.lineSeparator()); } diff --git a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json index cfb731d0..c00cb98e 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidAndValidPersonAddressBook.json @@ -4,15 +4,15 @@ "phone": "9482424", "email": "hans@example.com", "address": "4th street", - "group": "NA" + "group": "N/A" }, { "name": "Person With Invalid Phone Field", "phone": "948asdf2424", "email": "hans@example.com", "address": "4th street", - "group": "NA" + "group": "N/A" } ], "groups" : [ { - "group" : "NA" + "group" : "N/A" } ] } diff --git a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json b/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json index 3ac3fc16..2cf5825a 100644 --- a/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonAddressBookStorageTest/invalidPersonAddressBook.json @@ -4,9 +4,9 @@ "phone": "9482424", "email": "hans@example.com", "address": "4th street", - "group" : "NA" + "group" : "N/A" } ], "groups" : [ { - "group" : "NA" + "group" : "N/A" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json index a2199537..81500505 100644 --- a/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/duplicatePersonAddressBook.json @@ -5,15 +5,15 @@ "email": "alice@example.com", "address": "123, Jurong West Ave 6, #08-111", "tagged": [ "friends" ], - "group": "NA" + "group": "N/A" }, { "name": "Alice Pauline", "phone": "94351253", "email": "pauline@example.com", "address": "4th street", - "group": "NA" + "group": "N/A" } ], "groups" : [ { - "group" : "NA" + "group" : "N/A" } ] } diff --git a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json index 95e178d5..160abd30 100644 --- a/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json +++ b/src/test/data/JsonSerializableAddressBookTest/invalidPersonAddressBook.json @@ -4,9 +4,9 @@ "phone": "9482424", "email": "invalid@email!3e", "address": "4th street", - "group" : "NA" + "group" : "N/A" } ], "groups" : [ { - "group" : "NA" + "group" : "N/A" } ] } From 55ea76dacc161daf65feaa377ab1546cd42ff899 Mon Sep 17 00:00:00 2001 From: Tay Jun Wen Date: Fri, 19 Mar 2021 20:24:54 +0800 Subject: [PATCH 09/19] fixed checkstyle --- data/addressbook.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/addressbook.json b/data/addressbook.json index 7aa0eded..353ba839 100644 --- a/data/addressbook.json +++ b/data/addressbook.json @@ -65,4 +65,4 @@ }, { "group" : "C" } ] -} \ No newline at end of file +} From dc6eb20af3050f0d0e9e2f833d761fd3037da207 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Fri, 19 Mar 2021 20:28:30 +0800 Subject: [PATCH 10/19] 1. make RenameGroup index to start from 2 --- .../java/seedu/address/logic/commands/RenameGroupCommand.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java index 3b8e147e..e7b375bd 100644 --- a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java @@ -40,7 +40,9 @@ public CommandResult execute(Model model) throws CommandException { throw new CommandException(MESSAGE_INVALID_INDEX); } - model.renameGroup(targetIndex.getOneBased(), group.toString()); + //To '+1' here in the index is due to the groupList is start from 2. Index 1 is reserved for N/A, + // which shouldn't be renamed + model.renameGroup(targetIndex.getOneBased() + 1, group.toString()); return new CommandResult(String.format(MESSAGE_SUCCESS, targetIndex.getOneBased(), group.toString())); } } From 0ad79641171ab17c266967c32ca517068ca7cf11 Mon Sep 17 00:00:00 2001 From: Tay Jun Wen <43071400+tototto@users.noreply.github.com> Date: Fri, 19 Mar 2021 20:38:08 +0800 Subject: [PATCH 11/19] Update with new command and changed existing cmd --- docs/UserGuide.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 81b289e3..d0d12763 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -92,11 +92,14 @@ Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]…​`
:bulb: **Tip:** A person can have any number of tags (including 0) +A person who is created will have have default group created. The group shall be "N/A". +If a person is created with a group, then it can be pre-assigned with a user given group.
Examples: * `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` * `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` +* * `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal g/GroupA` ### Listing all persons : `list` @@ -211,16 +214,16 @@ Format: `rename INDEX [n/NAME]` Examples: * `rename 1 n/PERFORMANCE ` Rename the group with index 1 into PERFORMANCE. -### List all persons in a group: `list -g [group name]` +### List all persons in a group: `listfromgrp g/[group name]` Lists all persons in a particular group. -Format: `list -g [group_name]` +Format: `list g/[group_name]` * The group name is case-insensitive. e.g IPPT will match ippt Examples: -* `list -g PERFORMANCE ` Lists all persons in PERFORMANCE. +* `list g/PERFORMANCE ` Lists all persons in PERFORMANCE. ### Deleting a group: `deletegrp [Index Number]` @@ -238,6 +241,16 @@ Examples: * `List all` followed by `delete 1` deletes the 1st group in the results of the `find` command. +### Deleting every person from a group: `deletepsngrp g/[Group Name]` + +Deletes every person from that group in the addressbook. + +Format: `deletepsngrp g/GroupA` + +* Deletes every person currently assigned to that group. +* If there is no person to delete, then nothing will happen. + + ### Archiving data files `[coming in v2.0]` _Details coming soon ..._ From 96a984c9100fcb7c627aa6057a12f63ccfb71bcf Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Sat, 20 Mar 2021 15:42:03 +0800 Subject: [PATCH 12/19] refine test cases and remove unused methods --- src/main/java/seedu/address/model/Model.java | 6 ------ src/main/java/seedu/address/model/ModelManager.java | 5 ----- .../seedu/address/logic/commands/AddCommandTest.java | 10 ++++++++++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java index 928c4a03..a60e089f 100644 --- a/src/main/java/seedu/address/model/Model.java +++ b/src/main/java/seedu/address/model/Model.java @@ -124,12 +124,6 @@ public static Predicate predicateShowAllPersonsInGroup(Group group) { */ void addGroup(Group toAdd); - /** - * return the group at the index i in the group list. - * {@code i} an int index . - */ - Group getGroupByIndex(int i); - /** * return the group at the index i in the group list. * {@code i} an int index . diff --git a/src/main/java/seedu/address/model/ModelManager.java b/src/main/java/seedu/address/model/ModelManager.java index bef4b434..8fac3530 100644 --- a/src/main/java/seedu/address/model/ModelManager.java +++ b/src/main/java/seedu/address/model/ModelManager.java @@ -164,11 +164,6 @@ public void addGroup(Group toAdd) { GroupList.addGroup(toAdd); } - @Override - public Group getGroupByIndex(int i) { - return GroupList.getGroup(i); - } - @Override public int getGroupSize() { return GroupList.getGroupListSize(); diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index 4d1b13ca..1a8b9e77 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -174,6 +174,16 @@ public boolean hasGroup(Group toAdd) { public void addGroup(Group toAdd) { return; } + + @Override + public void renameGroup(int i, String name) { + throw new AssertionError("This method should not be called."); + } + + @Override + public int getGroupSize() { + throw new AssertionError("This method should not be called."); + } } /** From c31fa06e275302fbb8607bd7526168d214c133a2 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Sat, 20 Mar 2021 15:54:12 +0800 Subject: [PATCH 13/19] Update AddCommandTest.java --- .../java/seedu/address/logic/commands/AddCommandTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/seedu/address/logic/commands/AddCommandTest.java b/src/test/java/seedu/address/logic/commands/AddCommandTest.java index 9c33aa11..dfa4cb82 100644 --- a/src/test/java/seedu/address/logic/commands/AddCommandTest.java +++ b/src/test/java/seedu/address/logic/commands/AddCommandTest.java @@ -183,7 +183,9 @@ public void renameGroup(int i, String name) { @Override public int getGroupSize() { throw new AssertionError("This method should not be called."); - + } + + @Override public ArrayList getPersonListInThisGroup(Group group) { return null; } From 923f885b12173ce29281341e6a4f0e73f9a5faf7 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Sat, 20 Mar 2021 16:05:03 +0800 Subject: [PATCH 14/19] Update RenameGroupCommand.java bug fixed in RenameGroupCommand --- .../address/logic/commands/RenameGroupCommand.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java index e7b375bd..53224656 100644 --- a/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java +++ b/src/main/java/seedu/address/logic/commands/RenameGroupCommand.java @@ -14,11 +14,11 @@ public class RenameGroupCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Rename the group identified by the index number used in the displayed group list and a specified " + "new name.\n" - + "Parameters: INDEX (must be a positive integer) " + PREFIX_GROUP + " GROUP_NAME\n" - + "Example: " + COMMAND_WORD + " 1" + PREFIX_GROUP + "NEW_GROUP_NAME"; + + "Parameters: INDEX (must be a positive integer from 1 to the size of group list) " + + PREFIX_GROUP + " GROUP_NAME\n" + + "Example: " + COMMAND_WORD + " 1 " + PREFIX_GROUP + "NEW_GROUP_NAME"; public static final String MESSAGE_SUCCESS = "Group index %1$d rename successfully: %2$s"; - public static final String MESSAGE_INVALID_INDEX = "The index specified is invalid."; private final Index targetIndex; private final Group group; @@ -36,8 +36,8 @@ public RenameGroupCommand(Index targetIndex, Group group) { public CommandResult execute(Model model) throws CommandException { requireNonNull(model); - if (targetIndex.getOneBased() <= 0 || targetIndex.getOneBased() > model.getGroupSize()) { - throw new CommandException(MESSAGE_INVALID_INDEX); + if (targetIndex.getOneBased() <= 0 || targetIndex.getOneBased() >= model.getGroupSize()) { + throw new CommandException(MESSAGE_USAGE); } //To '+1' here in the index is due to the groupList is start from 2. Index 1 is reserved for N/A, From 2eae91b299925fcb97903e1f8495d2eb1c189b04 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Sat, 20 Mar 2021 16:30:22 +0800 Subject: [PATCH 15/19] Update UserGuide.md --- docs/UserGuide.md | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 57e0dea4..3c806200 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -29,11 +29,15 @@ Addressbook NS Edition (ABNS) is a **desktop app for managing contacts, optimize * **`listGroup all`** : Shows a list of all groups in the address book. - * **`create -g`** : Creates a new group to the address book. + * **`create`** : Creates a new group to the address book. - * **`list -g [group name]`** : Lists all persons in a particular group. + * **`list g/[GROUP NAME]`** : Lists all persons in a particular group. - * **`delete -g`** : Deletes the specified group from the address book. + * **`delete`** : Deletes the specified group from the address book. + + * **`assignptg`** : Assign a person by using his name to the specified group. + + * **`rename`** : Renaming an existing group to another name. * **`list`** : Lists all contacts. @@ -180,11 +184,11 @@ AddressBook data are saved as a JSON file `[JAR file location]/data/addressbook. If your changes to the data file makes its format invalid, AddressBook will discard all data and start with an empty data file at the next run. -### Creating a group: `create g/` +### Creating a group: `create` Creates a new group to the Address book NS Edition -Format: `create g/` +Format: `create g/` Examples: * `create g/FITNESS` Creates a group called Fitness @@ -199,26 +203,39 @@ Format: `show` Examples: * `show` Lists all groups - -### Rename the group: `rename -g` +### Rename the group: `rename` Rename an existing group to another name. -Format: `rename INDEX [g/NAME]` +Format: `rename g/` * Rename the group at the specified INDEX * The index refers to the index number shown in the displayed group list. * The index must be a positive integer 1, 2, 3, … * Existing values will be updated to the input values. +* Invalid index and command will trigger a message to tell the correct command format Examples: * `rename 1 g/PERFORMANCE ` Rename the group with index 1 into PERFORMANCE. -### List all persons in a group: `listfromgrp g/[group name]` +### Assign a person to group: `assignptg` + +Assign a person to a specified group by using person's name. + +Format: `assignptg n/ g/` + +* Using the person's name to assign +* Both person and group should exist. +* Invalid command or format will trigger an error message + +Examples: +* `assignptg n/Alice g/TEST ` Assign Alice to the group TEST. + +### List all persons in a group: `listfromgrp` Lists all persons in a particular group. -Format: `list g/[group_name]` +Format: `list g/` * The group name is case-insensitive. e.g IPPT will match ippt @@ -226,7 +243,7 @@ Examples: * `list g/PERFORMANCE ` Lists all persons in PERFORMANCE. -### Deleting a group: `deletegrp [Index Number]` +### Deleting a group: `deletegrp` Deletes the specified group from the address book. @@ -241,11 +258,11 @@ Examples: * `List all` followed by `delete 1` deletes the 1st group in the results of the `find` command. -### Deleting every person from a group: `deletepsngrp g/[Group Name]` +### Deleting every person from a group: `deletepsngrp` Deletes every person from that group in the addressbook. -Format: `deletepsngrp g/GroupA` +Format: `deletepsngrp g/` * Deletes every person currently assigned to that group. * If there is no person to delete, then nothing will happen. From 6ee2cde366033079ab7ec07bcaab6884741646e7 Mon Sep 17 00:00:00 2001 From: ZhengShijie Date: Sun, 21 Mar 2021 08:57:46 +0800 Subject: [PATCH 16/19] Update Ui.png --- docs/images/Ui.png | Bin 14607 -> 35808 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5bd77847aa2429edac366ebe3e00650b6dd909d8..17f53cd10c96d33ccd08dd0e1f1a4dae1584743d 100644 GIT binary patch literal 35808 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 RAXge19gVx{rMDi1{6Bg4z)AoB From 16eaeda698ab11bd96bae823f04211e11c1c0b92 Mon Sep 17 00:00:00 2001 From: ZhengShijieNUS <43492731+ZhengShijieNUS@users.noreply.github.com> Date: Sun, 21 Mar 2021 09:03:20 +0800 Subject: [PATCH 17/19] Update index.md --- docs/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index 7601dbaa..5e85a80b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,17 @@ --- layout: page -title: AddressBook Level-3 +title: Addressbook NS Edition (ABNS) --- -[![CI Status](https://github.com/se-edu/addressbook-level3/workflows/Java%20CI/badge.svg)](https://github.com/se-edu/addressbook-level3/actions) +[![CI Status](https://github.com/AY2021S2-TIC4002-F18-3/tp2/workflows/Java%20CI/badge.svg)](https://github.com/AY2021S2-TIC4002-F18-3/tp2/actions) [![codecov](https://codecov.io/gh/se-edu/addressbook-level3/branch/master/graph/badge.svg)](https://codecov.io/gh/se-edu/addressbook-level3) ![Ui](images/Ui.png) -**AddressBook is a desktop application for managing your contact details.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). +**Addressbook NS Edition (ABNS) is a desktop application for managing contact details and grouping people.** While it has a GUI, most of the user interactions happen using a CLI (Command Line Interface). -* If you are interested in using AddressBook, head over to the [_Quick Start_ section of the **User Guide**](UserGuide.html#quick-start). -* If you are interested about developing AddressBook, the [**Developer Guide**](DeveloperGuide.html) is a good place to start. +* If you are interested in using Addressbook NS Edition (ABNS), head over to the [_Quick Start_ section of the **User Guide**](https://ay2021s2-tic4002-f18-3.github.io/tp2/UserGuide.html#quick-start). +* If you are interested about developing Addressbook NS Edition (ABNS), the [**Developer Guide**](https://ay2021s2-tic4002-f18-3.github.io/tp2/DeveloperGuide.html) is a good place to start. **Acknowledgements** From 56ebca35ab8c061fc8629ac1f1d7d46524509538 Mon Sep 17 00:00:00 2001 From: "DESKTOP-K455E2E\\hongj" Date: Sun, 21 Mar 2021 22:15:13 +0800 Subject: [PATCH 18/19] no message --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index be2d2905..3e479937 100644 --- a/build.gradle +++ b/build.gradle @@ -70,3 +70,7 @@ shadowJar { } defaultTasks 'clean', 'test' + +run { + enableAssertions = true +} From 7a7bb83e357a9cfa12813cb8f61d5b08c5e540f7 Mon Sep 17 00:00:00 2001 From: "DESKTOP-K455E2E\\hongj" Date: Sun, 21 Mar 2021 22:21:20 +0800 Subject: [PATCH 19/19] Update Developer Guide and Enable Assertions --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index eb813207..7469cd71 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -258,6 +258,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli | `* * *` | user | delete a group | remove the groups that I no longer need | | `* * *` | user | list all groups | keep track of what has been created in the system | | `* * *` | user | list all persons in a group | give a punishment or a reward to soldiers in the specific group | +| `* * *` | user | load groups from json file | the previous record will be maintained | | `* * *` | user | find a person by name | locate details of persons without having to go through the entire list | | `* *` | user | hide private contact details | minimize chance of someone else seeing them by accident | | `*` | user with many persons in the address book | sort persons by name | locate a person easily |