Skip to content

Commit

Permalink
Merge branch 'master' into branch-updateUserGuide
Browse files Browse the repository at this point in the history
  • Loading branch information
SwaminathanViswa authored Nov 5, 2024
2 parents 9aa2641 + f2585ff commit 45ec3d9
Show file tree
Hide file tree
Showing 14 changed files with 547 additions and 26 deletions.
2 changes: 2 additions & 0 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ konTActs is a **desktop app for managing contacts, optimized for use via a Comma

The help command opens the help window that shows the link to this user guide. The window adds access to copy the url to the clipboard or directly launch this user guide from the browser.

A compact reference guide is also provided for quick reference.

<box type="definition" icon=":fa-solid-spell-check:" light>

<md>**Format: `help`**</md>
Expand Down
Binary file modified docs/images/helpMessage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Messages {
public static final String MESSAGE_MARK_ALREADY_SUCCESS = "Attendance is already marked for this student!";
public static final String MESSAGE_UNMARK_ALREADY_SUCCESS = "Attendance is already unmarked for this student";
public static final String MESSAGE_UNMARK_SUCCESS = "%1$s is marked as absent for week %2$d";
public static final String MESSAGE_INVALID_ASSIGNMENT_NAME = "Invalid assignment name: %1$s";


/**
Expand Down
116 changes: 116 additions & 0 deletions src/main/java/seedu/address/logic/commands/RemoveGradeCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_ASSIGNMENT_NAME;
import static seedu.address.logic.Messages.MESSAGE_INVALID_PERSON_DISPLAYED_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ASSIGNMENT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.ParserUtil.parseName;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.Model;
import seedu.address.model.assignment.Assignment;
import seedu.address.model.person.Email;
import seedu.address.model.person.Github;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.Phone;
import seedu.address.model.person.Telegram;
import seedu.address.model.tag.Tag;

/**
* Remove assignment grades from an existing person in the address book.
*/
public class RemoveGradeCommand extends Command {
public static final String COMMAND_WORD = "removeGrade";
public static final String MESSAGE_USAGE =
COMMAND_WORD
+ ": Removes a grade of an assignment from the person.\n"
+ "Parameters: "
+ PREFIX_NAME
+ "NAME "
+ PREFIX_ASSIGNMENT
+ "ASSIGNMENT\n"
+ "Example: "
+ COMMAND_WORD
+ " "
+ PREFIX_NAME
+ "John Doe "
+ PREFIX_ASSIGNMENT
+ "Ex09";

public static final String MESSAGE_SUCCESS = "Assignment %1$s removed from %2$s";
public static final String MESSAGE_FAILURE = "Assignment %s does not exist for %s.";
private final Name personName;
private final String assignmentName;

/**
* @param personName Name of the person.
* @param assignmentName Name of assignment.
*/
public RemoveGradeCommand(String personName, String assignmentName) throws ParseException {
requireAllNonNull(personName, assignmentName);
this.personName = parseName(personName);
this.assignmentName = assignmentName;
}


static Person createPersonWithRemovedGrade(Person person, String assignmentName) {
assert person != null;
Name name = person.getName();
Phone phone = person.getPhone();
Email email = person.getEmail();
Set<Tag> tags = person.getTags();
Telegram telegram = person.getTelegram();
Github github = person.getGithub();
Set<Integer> weeksAttended = person.getWeeksPresent();

Map<String, Assignment> assignment = person.getAssignment();
assignment.remove(assignmentName);

return new Person(name, phone, email, telegram, github, assignment, weeksAttended, tags);
}

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

// check if assignment is in predefined list
if (!model.hasAssignment(assignmentName)) {
throw new CommandException(String.format(MESSAGE_INVALID_ASSIGNMENT_NAME, assignmentName));
}

Person person = model.getPerson(personName)
.orElseThrow(() ->
new CommandException(MESSAGE_INVALID_PERSON_DISPLAYED_NAME));

// Check if the assignment is already missing from the person's record
if (!person.getAssignment().containsKey(assignmentName)) {
throw new CommandException(
String.format(MESSAGE_FAILURE, assignmentName, personName));
}

model.setPerson(person, createPersonWithRemovedGrade(person, model.getAssignmentName(assignmentName)));
return new CommandResult(String.format(MESSAGE_SUCCESS, assignmentName, personName));
}

@Override
public String toString() {
return personName + " " + assignmentName;
}

@Override
public boolean equals(Object other) {
if (other instanceof RemoveGradeCommand otherCommand) {
return Objects.equals(otherCommand.personName, personName)
&& Objects.equals(otherCommand.assignmentName, assignmentName);
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import seedu.address.logic.commands.ImportCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.MarkCommand;
import seedu.address.logic.commands.RemoveGradeCommand;
import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.commands.UnmarkCommand;
import seedu.address.logic.commands.ViewCommand;
Expand Down Expand Up @@ -92,6 +93,9 @@ public Command parseCommand(String userInput) throws ParseException {
case AddGradeCommand.COMMAND_WORD:
return new AddGradeCommandParser().parse(arguments);

case RemoveGradeCommand.COMMAND_WORD:
return new RemoveGradeCommandParser().parse(arguments);

case FilterCommand.COMMAND_WORD:
return new FilterCommandParser().parse(arguments);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ASSIGNMENT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;

import java.util.stream.Stream;

import seedu.address.logic.commands.RemoveGradeCommand;
import seedu.address.logic.parser.exceptions.ParseException;

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

@Override
public RemoveGradeCommand parse(String args) throws ParseException {
if (args.isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemoveGradeCommand.MESSAGE_USAGE));
}

ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_ASSIGNMENT);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ASSIGNMENT)
|| !argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, RemoveGradeCommand.MESSAGE_USAGE));
}

String name = argMultimap.getValue(PREFIX_NAME).orElse("").trim();
if (name.isEmpty()) {
throw new ParseException("Name cannot be empty.");
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_ASSIGNMENT);

String assignmentName = argMultimap.getValue(PREFIX_ASSIGNMENT).orElse("").trim();
if (assignmentName.isEmpty()) {
throw new ParseException("Assignment name cannot be empty.");
}

return new RemoveGradeCommand(name, assignmentName);
}

/**
* 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());
}
}
30 changes: 30 additions & 0 deletions src/main/java/seedu/address/ui/CommandDetailCard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package seedu.address.ui;

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Label;

/**
* A UI component that displays information of a command and its use case in the {@code HelpWindow}.
*/
public class CommandDetailCard extends UiPart<Node> {
private static final String FXML = "CommandDetailCard.fxml";

@FXML
private Label command;
@FXML
private Label commandDetails;

/**
* Creates a {@code CommandDetailCard} with the given command word and command details of the {@code Command}.
*
* @param commandWord command word used to call the command.
* @param commandDetails details of how to use the command.
*/
public CommandDetailCard(String commandWord, String commandDetails) {
super(FXML);
this.command.setText(commandWord);
this.commandDetails.setText(commandDetails);
}

}
63 changes: 63 additions & 0 deletions src/main/java/seedu/address/ui/HelpWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,34 @@
import java.net.URISyntaxException;
import java.util.logging.Logger;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.stage.Stage;
import seedu.address.commons.core.FunctionalBrowser;
import seedu.address.commons.core.LogsCenter;
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.AddGradeCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.ExportCommand;
import seedu.address.logic.commands.FilterCommand;
import seedu.address.logic.commands.FindCommand;
import seedu.address.logic.commands.GitHubCommand;
import seedu.address.logic.commands.ImportCommand;
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.MarkCommand;
import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.commands.UnmarkCommand;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.commands.exceptions.CommandException;

/**
Expand All @@ -24,6 +44,26 @@ public class HelpWindow extends UiPart<Stage> {

private static final Logger logger = LogsCenter.getLogger(HelpWindow.class);
private static final String FXML = "HelpWindow.fxml";
private static final CommandDetailCard[] COMMANDS = {
new CommandDetailCard(AddCommand.COMMAND_WORD, AddCommand.MESSAGE_USAGE),
new CommandDetailCard(AddGradeCommand.COMMAND_WORD, AddGradeCommand.MESSAGE_USAGE),
new CommandDetailCard(ClearCommand.COMMAND_WORD, ClearCommand.MESSAGE_USAGE),
new CommandDetailCard(DeleteCommand.COMMAND_WORD, DeleteCommand.MESSAGE_USAGE),
new CommandDetailCard(EditCommand.COMMAND_WORD, EditCommand.MESSAGE_USAGE),
new CommandDetailCard(ExportCommand.COMMAND_WORD, ExportCommand.MESSAGE_USAGE),
new CommandDetailCard(FilterCommand.COMMAND_WORD, FilterCommand.MESSAGE_USAGE),
new CommandDetailCard(FindCommand.COMMAND_WORD, FindCommand.MESSAGE_USAGE),
new CommandDetailCard(GitHubCommand.COMMAND_WORD, GitHubCommand.MESSAGE_USAGE),
new CommandDetailCard(ImportCommand.COMMAND_WORD, ImportCommand.MESSAGE_USAGE),
new CommandDetailCard(ListCommand.COMMAND_WORD, ListCommand.MESSAGE_USAGE),
new CommandDetailCard(MarkCommand.COMMAND_WORD, MarkCommand.MESSAGE_USAGE),
new CommandDetailCard(UnmarkCommand.COMMAND_WORD, UnmarkCommand.MESSAGE_USAGE),
new CommandDetailCard(SortCommand.COMMAND_WORD, SortCommand.MESSAGE_USAGE),
new CommandDetailCard(ViewCommand.COMMAND_WORD, ViewCommand.MESSAGE_USAGE),
new CommandDetailCard(ExitCommand.COMMAND_WORD, ExitCommand.MESSAGE_USAGE),
};

private final ObservableList<CommandDetailCard> commandList = FXCollections.observableArrayList();

@FXML
private Button copyButton;
Expand All @@ -33,6 +73,9 @@ public class HelpWindow extends UiPart<Stage> {
@FXML
private Label helpMessage;

@FXML
private ListView<CommandDetailCard> commandDetailCardListView;

/**
* Creates a new HelpWindow.
*
Expand All @@ -41,6 +84,26 @@ public class HelpWindow extends UiPart<Stage> {
public HelpWindow(Stage root) {
super(FXML, root);
helpMessage.setText(HELP_MESSAGE);

commandList.addAll(COMMANDS);
commandDetailCardListView.setItems(commandList);
commandDetailCardListView.setCellFactory(listView -> new CommandListViewCell());
}

/**
* Custom {@code ListCell} that displays the graphics of a command detail using a {@code CommandDetailCard}.
*/
class CommandListViewCell extends ListCell<CommandDetailCard> {
@Override
protected void updateItem(CommandDetailCard card, boolean empty) {
super.updateItem(card, empty);

if (empty || card == null) {
setGraphic(null);
} else {
setGraphic(card.getRoot());
}
}
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/main/resources/view/CommandDetailCard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#commandDetailCard {
-fx-background-color: derive(#1d1d1d, 25%);
}

#command {
-fx-font-family: "Segoe UI Semibold";
-fx-text-fill: white;
-fx-font-size: 16px;
-fx-padding: 10 0 5 0
}

#commandDetails {
-fx-text-fill: white;
}

#separator {
-fx-border-color: derive(#1d1d1d, 25%);
}
25 changes: 25 additions & 0 deletions src/main/resources/view/CommandDetailCard.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>


<?import java.net.URL?>

<VBox fx:id="commandDetailCard" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1">
<stylesheets>
<URL value="@CommandDetailCard.css" />
</stylesheets>

<padding>
<Insets top="5" right="5" bottom="5" left="15" />
</padding>

<Label fx:id="command" styleClass="cell_small_label" text="\$command" />
<Label fx:id="commandDetails" styleClass="cell_small_label" text="\$commandDetails" />

</VBox>
Loading

0 comments on commit 45ec3d9

Please sign in to comment.