Skip to content

Commit

Permalink
Merge pull request #203 from oeggy03/branch-fix-ui-2
Browse files Browse the repository at this point in the history
Fix UI related bugs (Without changing existing Ui/ implementation except to fix bugs)
  • Loading branch information
lunaroddity authored Nov 9, 2023
2 parents c3f1855 + aaa0229 commit 2f2e486
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 131 deletions.
31 changes: 14 additions & 17 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,16 @@ It is recommended to create a new empty folder to act as a home folder.
* Note that the app contains some sample data.<br>
![Ui](images/Ui.png)

(Placeholder here to remind us to have another UI image where each section of the UI is boxed up and
described/explained to the user in detail. -- For CS2101)

1. Type the command in the command box and press Enter to run it.
2. Our Ui has 6 main sections:
![UiBoxed](images/UiBoxed.png)
* **MenuBar**: Provides quick access to essential features of "Help" and "File".
* **Command Box**: Allows you to type in your commands.
* **Command Result Box**: Displays the result of running a command.
* **Display Box**: Displays all the details of a person or a company after certain commands are run.
* **List of People**: Displays brief details of every person added. The index, name and tags for each person are displayed here.
* **List of Companies**: Displays brief details of every company added. The index, name, tags and the next internship interview date (represented by the "Next:" field) for each company are displayed here.

3. Type the command in the command box and press Enter to run it.
Here are some examples of commands you can run:

* `list p` : Lists all contacts.
Expand All @@ -103,7 +109,7 @@ described/explained to the user in detail. -- For CS2101)

* `exit` : Exits the app.

1. Refer to the [Features](#features) below for details of each command.
4. Refer to the [Features](#features) below for details of each command.
------------------------------------------------------------------------------------------------------------------------

## Features
Expand Down Expand Up @@ -227,28 +233,19 @@ Have a quick look at all the people you know in the contact list.

Format: `list p`

* `list p` shows:
* `list p` shows the full list of all the people added, as boxed in red:
![list of all companies](images/listPersons.png)


### Listing all companies: `list c`

Have a quick look at all the companies you are interested in in the contact list.
Have a quick look at all the companies you are interested in the contact list.

Format: `list c`

* `list c` shows:
* `list c` shows the full list of all the companies added, as boxed in red:
![list of all companies](images/listCompanies.png)

### Listing all persons: `list p`

Have a quick look at all the people you know in the contact list.

Format: `list p`

* `list p` shows:
![list of all persons](images/listPersons.png)

### Viewing a person's contact: `view p`

Find out the specific details of your desired contact by viewing that person's contact.
Expand Down
Binary file added docs/images/UiBoxed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/listCompanies.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/listPersons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import static seedu.address.logic.parser.CliSyntax.PREFIX_DESCRIPTION;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SCHEDULED;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_COMPANIES;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_INTERNSHIPS;
import static seedu.address.model.Model.PREDICATE_SHOW_NO_COMPANIES;

import java.util.List;

Expand Down Expand Up @@ -69,6 +72,14 @@ public CommandResult execute(Model model) throws CommandException {
}

companyToAddTo.addInternship(internship);

// Updates the sorted list of internships so that the Ui updates properly.
companyToAddTo.updateFilteredInternshipList(PREDICATE_SHOW_ALL_INTERNSHIPS);

// This helps to "reset" the company list UI, otherwise the company card will not update.
model.updateFilteredCompanyList(PREDICATE_SHOW_NO_COMPANIES);
model.updateFilteredCompanyList(PREDICATE_SHOW_ALL_COMPANIES);

return new RegularCommandResult(String.format(MESSAGE_SUCCESS, Messages.formatInternship(internship)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_COMPANIES;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_INTERNSHIPS;
import static seedu.address.model.Model.PREDICATE_SHOW_NO_COMPANIES;

import java.util.ArrayList;
import java.util.List;

import seedu.address.commons.core.index.Index;
Expand Down Expand Up @@ -34,32 +36,35 @@ public DeleteInternshipCommand(Index targetCompanyIndex, Index targetInternshipI
this.targetCompanyIndex = targetCompanyIndex;
this.targetInternshipIndex = targetInternshipIndex;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Company> lastShownList = model.getFilteredCompanyList();
if (targetCompanyIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_COMPANY_DISPLAYED_INDEX);
}
Company companyToDelete = lastShownList.get(targetCompanyIndex.getZeroBased());
List<Internship> currInternships = companyToDelete.getInternshipList();
if (targetInternshipIndex.getZeroBased() >= currInternships.size()) {

Company companyToDeleteFrom = lastShownList.get(targetCompanyIndex.getZeroBased());

if (targetInternshipIndex.getZeroBased() >= companyToDeleteFrom.getInternshipList().size()) {
throw new CommandException(Messages.MESSAGE_INVALID_INTERNSHIP_DISPLAYED_INDEX);
}
List<Internship> updatedInternships = new ArrayList<>(currInternships);
updatedInternships.remove(targetInternshipIndex.getZeroBased());
Company updatedCompany = new Company(companyToDelete.getCompanyName(),
companyToDelete.getCompanyPhone(), companyToDelete.getCompanyEmail(),
companyToDelete.getCompanyDescription(), companyToDelete.getTags(),
updatedInternships);

model.setCompany(companyToDelete, updatedCompany);
model.updateFilteredCompanyList(Model.PREDICATE_SHOW_ALL_COMPANIES);

Internship internshipToDelete = companyToDeleteFrom.getInternshipAtIndex(targetInternshipIndex);
companyToDeleteFrom.removeInternship(internshipToDelete);

companyToDeleteFrom.updateFilteredInternshipList(PREDICATE_SHOW_ALL_INTERNSHIPS);

// This helps to "reset" the company list UI, otherwise the company card will not update.
model.updateFilteredCompanyList(PREDICATE_SHOW_NO_COMPANIES);
model.updateFilteredCompanyList(PREDICATE_SHOW_ALL_COMPANIES);

return new DisplayableCommandResult(
String.format(MESSAGE_SUCCESS,
this.targetInternshipIndex.getOneBased(),
companyToDelete.getCompanyName()),
companyToDelete);
companyToDeleteFrom.getCompanyName()),
companyToDeleteFrom);
}
@Override
public boolean equals(Object other) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_COMPANIES;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_INTERNSHIPS;
import static seedu.address.model.Model.PREDICATE_SHOW_NO_COMPANIES;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -65,13 +68,20 @@ public CommandResult execute(Model model) throws CommandException {
Internship internshipToEdit = companyToEdit.getInternshipAtIndex(internshipIndex);
Internship editedInternship = createEditedInternship(internshipToEdit, editInternshipDescriptor);

if (companyToEdit.hasInternship(editedInternship)) {
if (!internshipToEdit.getInternshipName().equals(editedInternship.getInternshipName())
&& companyToEdit.hasInternship(editedInternship)) {
throw new CommandException(MESSAGE_DUPLICATE_INTERNSHIP);
}

companyToEdit.setInternship(internshipToEdit, editedInternship);
model.setCompany(companyToEdit, companyToEdit);

companyToEdit.updateFilteredInternshipList(PREDICATE_SHOW_ALL_INTERNSHIPS);

// This helps to "reset" the company list UI, otherwise the company card will not update.
model.updateFilteredCompanyList(PREDICATE_SHOW_NO_COMPANIES);
model.updateFilteredCompanyList(PREDICATE_SHOW_ALL_COMPANIES);

return new DisplayableCommandResult(String.format(MESSAGE_SUCCESS, Messages.formatInternship(editedInternship)),
companyToEdit);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.company.Company;
import seedu.address.model.company.internship.Internship;
import seedu.address.model.company.internship.InternshipInterviewDateTime;
import seedu.address.model.person.Person;

Expand All @@ -17,6 +18,9 @@ public interface Model {
/** {@code Predicate} that always evaluate to true */
Predicate<Person> PREDICATE_SHOW_ALL_PERSONS = unused -> true;
Predicate<Company> PREDICATE_SHOW_ALL_COMPANIES = unused -> true;
// Predicate to display all internships
Predicate<Internship> PREDICATE_SHOW_ALL_INTERNSHIPS = unused -> true;
Predicate<Company> PREDICATE_SHOW_NO_COMPANIES = unused -> false;

/**
* Replaces user prefs data with the data in {@code userPrefs}.
Expand Down
92 changes: 60 additions & 32 deletions src/main/java/seedu/address/model/company/Company.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package seedu.address.model.company;

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

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.company.internship.Internship;
Expand All @@ -23,6 +28,27 @@
* Guarantees: details are present and not null, field values are validated, immutable.
*/
public class Company {
//Comparator for filterInternships
private static final Comparator<Internship> INTERNSHIP_COMPARATOR = (internship1, internship2) -> {
// Extract the interview date if it exists
Optional<LocalDateTime> date1 = internship1.getInternshipDateTime()
.map(InternshipInterviewDateTime::getInternshipDateTime);
Optional<LocalDateTime> date2 = internship2.getInternshipDateTime()
.map(InternshipInterviewDateTime::getInternshipDateTime);

// Check if both have no dates
if (date1.isEmpty() && date2.isEmpty()) {
return 0; // Both have no dates, leave them unsorted.
} else if (date1.isEmpty()) {
return 1; // Only internship2 has a date, place internship1 at the back.
} else if (date2.isEmpty()) {
return -1; // Only internship1 has a date, place internship2 at the back.
} else {
// Both internships have dates, compare based on the interview date.
return date1.get().compareTo(date2.get());
}
};

// Identity fields
private final CompanyName companyName;
private final CompanyPhone phone;
Expand All @@ -32,6 +58,9 @@ public class Company {
private final CompanyDescription companyDescription;
private final Set<Tag> tags = new HashSet<>();
private final UniqueInternshipList internships;
private final FilteredList<Internship> filteredInternshipsRaw;
private final SortedList<Internship> filteredInternships;


/**
* Constructs a company without any Internships.
Expand All @@ -47,6 +76,8 @@ public Company(CompanyName companyName, CompanyPhone phone,
this.companyDescription = companyDescription;
this.tags.addAll(tags);
this.internships = new UniqueInternshipList();
this.filteredInternshipsRaw = new FilteredList<>(this.internships.asUnmodifiableObservableList());
this.filteredInternships = new SortedList<>(this.filteredInternshipsRaw, INTERNSHIP_COMPARATOR);
}

/**
Expand All @@ -67,6 +98,9 @@ public Company(CompanyName companyName, CompanyPhone phone,
for (Internship i : internships) {
this.internships.add(i);
}

this.filteredInternshipsRaw = new FilteredList<>(this.internships.asUnmodifiableObservableList());
this.filteredInternships = new SortedList<>(this.filteredInternshipsRaw, INTERNSHIP_COMPARATOR);
}

public CompanyName getCompanyName() {
Expand Down Expand Up @@ -98,7 +132,7 @@ public Set<Tag> getTags() {
* The internship must not already exist in the address book.
*/
public void addInternship(Internship toAdd) {
internships.add(toAdd);
this.internships.add(toAdd);
}

/**
Expand All @@ -112,7 +146,7 @@ public boolean hasInternship(Internship internship) {
* Returns the Internship at the specified index.
*/
public Internship getInternshipAtIndex(Index i) {
return this.internships.get(i.getZeroBased());
return this.filteredInternships.get(i.getZeroBased());
}

/**
Expand All @@ -122,47 +156,41 @@ public void setInternship(Internship target, Internship internship) {
this.internships.setInternship(target, internship);
}

/**
* Returns an ObservableList of internships.
*/
public ObservableList<Internship> getInternshipList() {
return internships.asUnmodifiableObservableList();
public void removeInternship(Internship internshipToRemove) {
this.internships.remove(internshipToRemove);
}

/**
* Returns the internship with the closest and most urgent Interview Date and Time.
* Updates the filtered list of internships with a given predicate.
*
* @return The most urgent Internship.
* @param predicate The predicate.
*/
public Optional<Internship> getMostUrgentInternship() {
LocalDateTime now = LocalDateTime.now();
Optional<Internship> mostUrgent = Optional.empty();

for (Internship internship : internships.asUnmodifiableObservableList()) {
Optional<InternshipInterviewDateTime> interviewDateTime = internship.getInternshipDateTime();

if (interviewDateTime.isPresent()) {
LocalDateTime interviewDate = interviewDateTime.get().getInternshipDateTime();

if (interviewDate.isAfter(now)) {
if (mostUrgent.isEmpty() || interviewDate.isBefore(mostUrgent.get().getInternshipDateTime()
.get().getInternshipDateTime())) {
mostUrgent = Optional.of(internship);
}
}
}
}

return mostUrgent;
public void updateFilteredInternshipList(Predicate<Internship> predicate) {
requireNonNull(predicate);
filteredInternshipsRaw.setPredicate(predicate);
filteredInternships.setComparator(INTERNSHIP_COMPARATOR);
}

/**
* Returns an ObservableList of Internship objects, sorted by the one with the most recent date and time first.
*
* @return The ObservableList of Internship objects under this company.
*/
public ObservableList<Internship> getInternshipsAsSortedObservableList() {
return this.internships.getInternshipsAsSortedObservableList();
public ObservableList<Internship> getInternshipList() {
return filteredInternships;
}

/**
* Returns the internship with the closest and most urgent Interview Date and Time.
*
* @return The most urgent Internship.
*/
public Optional<Internship> getMostUrgentInternship() {
if (!filteredInternships.isEmpty()) {
return Optional.of(this.filteredInternships.get(0));
} else {
return Optional.empty();
}
}

/**
Expand Down Expand Up @@ -215,7 +243,7 @@ public int hashCode() {
*/
public String toStringInternships() {
StringBuilder result = new StringBuilder("[");
for (Internship i : this.internships.asUnmodifiableObservableList()) {
for (Internship i : this.filteredInternships) {
result.append(i.toString()).append(", ");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public CompanyDateComparator(Predicate<InternshipInterviewDateTime> datePredicat
@Override
public int compare(Company company1, Company company2) {
Stream<InternshipInterviewDateTime> company1Dates = company1
.getInternshipsAsSortedObservableList()
.getInternshipList()
.stream()
.flatMap(internship -> Stream
.ofNullable(internship
Expand All @@ -29,7 +29,7 @@ public int compare(Company company1, Company company2) {
.filter(datePredicate);

Stream<InternshipInterviewDateTime> company2Dates = company2
.getInternshipsAsSortedObservableList()
.getInternshipList()
.stream()
.flatMap(internship -> Stream
.ofNullable(internship
Expand Down
Loading

0 comments on commit 2f2e486

Please sign in to comment.