Skip to content

Commit

Permalink
Merge pull request #179 from quelinxiao/update-tutorial-files
Browse files Browse the repository at this point in the history
refactor person to employee in tutorial files
  • Loading branch information
PyromancerBoom authored Apr 14, 2024
2 parents 3030056 + db805ea commit a06f82c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 54 deletions.
2 changes: 1 addition & 1 deletion docs/SettingUp.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ If you plan to use Intellij IDEA (highly recommended):

1. **Learn the design**

When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [AddressBook’s architecture](DeveloperGuide.md#architecture).
When you are ready to start coding, we recommend that you get some sense of the overall design by reading about [ContactSwift's architecture](DeveloperGuide.md#architecture).

1. **Do the tutorials**
These tutorials will help you get acquainted with the codebase.
Expand Down
54 changes: 27 additions & 27 deletions docs/tutorials/AddRemark.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ If you are stuck, check out the sample

## Add `Remark` to the model

Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of employee data. We achieve that by working with the `Person` model. Each field in a Person is implemented as a separate class (e.g. a `Name` object represents the employee’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a employee.
Now that we have all the information that we need, let’s lay the groundwork for propagating the remarks added into the in-memory storage of employee data. We achieve that by working with the `Employee` model. Each field in an Employee is implemented as a separate class (e.g. a `Name` object represents the employee’s name). That means we should add a `Remark` class so that we can use a `Remark` object to represent a remark given to a employee.

### Add a new `Remark` class

Expand All @@ -243,9 +243,9 @@ Let’s change `RemarkCommand` and `RemarkCommandParser` to use the new `Remark`

Without getting too deep into `fxml`, let’s go on a 5 minute adventure to get some placeholder text to show up for each employee.

Simply add the following to [`seedu.address.ui.PersonCard`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-639834f1e05afe2276a86372adf0fe5f69314642c2d93cfa543d614ce5a76688).
Simply add the following to [`seedu.address.ui.EmployeeCard`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-639834f1e05afe2276a86372adf0fe5f69314642c2d93cfa543d614ce5a76688).

**`PersonCard.java`:**
**`EmployeeCard.java`:**

```java
@FXML
Expand All @@ -255,9 +255,9 @@ private Label remark;

`@FXML` is an annotation that marks a private or protected field and makes it accessible to FXML. It might sound like Greek to you right now, don’t worry — we will get back to it later.

Then insert the following into [`main/resources/view/PersonListCard.fxml`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-d44c4f51c24f6253c277a2bb9bc440b8064d9c15ad7cb7ceda280bca032efce9).
Then insert the following into [`main/resources/view/EmployeeListCard.fxml`](https://github.com/se-edu/addressbook-level3/commit/850b78879582f38accb05dd20c245963c65ea599#diff-d44c4f51c24f6253c277a2bb9bc440b8064d9c15ad7cb7ceda280bca032efce9).

**`PersonListCard.fxml`:**
**`EmployeeListCard.fxml`:**

``` xml
<Label fx:id="remark" styleClass="cell_small_label" text="\$remark" />
Expand All @@ -267,21 +267,21 @@ That’s it! Fire up the application again and you should see something like thi

![$remark shows up in each entry](../images/add-remark/$Remark.png)

## Modify `Person` to support a `Remark` field
## Modify `Employee` to support a `Remark` field

Since `PersonCard` displays data from a `Person`, we need to update `Person` to get our `Remark` displayed!
Since `EmployeeCard` displays data from a `Employee`, we need to update `Employee` to get our `Remark` displayed!

### Modify `Person`
### Modify `Employee`

We change the constructor of `Person` to take a `Remark`. We will also need to define new fields and accessors accordingly to store our new addition.
We change the constructor of `Employee` to take a `Remark`. We will also need to define new fields and accessors accordingly to store our new addition.

### Update other usages of `Person`
### Update other usages of `Employee`

Unfortunately, a change to `Person` will cause other commands to break, you will have to modify these commands to use the updated `Person`!
Unfortunately, a change to `Employee` will cause other commands to break, you will have to modify these commands to use the updated `Employee`!

<box type="tip" seamless>

Use the `Find Usages` feature in IntelliJ IDEA on the `Person` class to find these commands.
Use the `Find Usages` feature in IntelliJ IDEA on the `Employee` class to find these commands.

</box>

Expand All @@ -290,7 +290,7 @@ Refer to [this commit](https://github.com/se-edu/addressbook-level3/commit/ce998

## Updating Storage

AddressBook stores data by serializing `JsonAdaptedPerson` into `json` with the help of an external library — Jackson. Let’s update `JsonAdaptedPerson` to work with our new `Person`!
AddressBook stores data by serializing `JsonAdaptedEmployee` into `json` with the help of an external library — Jackson. Let’s update `JsonAdaptedEmployee` to work with our new `Employee`!

While the changes to code may be minimal, the test data will have to be updated as well.

Expand All @@ -305,14 +305,14 @@ to see what the changes entail.

## Finalizing the UI

Now that we have finalized the `Person` class and its dependencies, we can now bind the `Remark` field to the UI.
Now that we have finalized the `Employee` class and its dependencies, we can now bind the `Remark` field to the UI.

Just add [this one line of code!](https://github.com/se-edu/addressbook-level3/commit/5b98fee11b6b3f5749b6b943c4f3bd3aa049b692)

**`PersonCard.java`:**
**`EmployeeCard.java`:**

```java
public PersonCard(Person employee, int displayedIndex) {
public EmployeeCard(Employee employee, int displayedIndex) {
//...
remark.setText(employee.getRemark().value);
}
Expand All @@ -326,31 +326,31 @@ After the previous step, we notice a peculiar regression — we went from di

### Update `RemarkCommand` and `RemarkCommandParser`

In this last step, we modify `RemarkCommand#execute()` to change the `Remark` of a `Person`. Since all fields in a `Person` are immutable, we create a new instance of a `Person` with the values that we want and
save it with `Model#setPerson()`.
In this last step, we modify `RemarkCommand#execute()` to change the `Remark` of a `Employee`. Since all fields in a `Employee` are immutable, we create a new instance of a `Employee` with the values that we want and
save it with `Model#setEmployee()`.

**`RemarkCommand.java`:**

```java
//...
public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Person: %1$s";
public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Person: %1$s";
public static final String MESSAGE_ADD_REMARK_SUCCESS = "Added remark to Employee: %1$s";
public static final String MESSAGE_DELETE_REMARK_SUCCESS = "Removed remark from Employee: %1$s";
//...
@Override
public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();
List<Employee> lastShownList = model.getFilteredEmployeeList();

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

Person employeeToEdit = lastShownList.get(index.getZeroBased());
Person editedEmployee = new Person(
Employee employeeToEdit = lastShownList.get(index.getZeroBased());
Employee editedEmployee = new Employee(
employeeToEdit.getName(), employeeToEdit.getPhone(), employeeToEdit.getEmail(),
employeeToEdit.getAddress(), remark, employeeToEdit.getTags());

model.setPerson(employeeToEdit, editedEmployee);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
model.setEmployee(employeeToEdit, editedEmployee);
model.updateFilteredEmployeeList(PREDICATE_SHOW_ALL_EMPLOYEES);

return new CommandResult(generateSuccessMessage(editedEmployee));
}
Expand All @@ -360,7 +360,7 @@ save it with `Model#setPerson()`.
* the remark is added to or removed from
* {@code employeeToEdit}.
*/
private String generateSuccessMessage(Person employeeToEdit) {
private String generateSuccessMessage(Employee employeeToEdit) {
String message = !remark.value.isEmpty() ? MESSAGE_ADD_REMARK_SUCCESS : MESSAGE_DELETE_REMARK_SUCCESS;
return String.format(message, employeeToEdit);
}
Expand Down
24 changes: 12 additions & 12 deletions docs/tutorials/RemovingFields.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
> — Antoine de Saint-Exupery
When working on an existing code base, you will most likely find that some features that are no longer necessary.
This tutorial aims to give you some practice on such a code 'removal' activity by removing the `address` field from `Person` class.
This tutorial aims to give you some practice on such a code 'removal' activity by removing the `address` field from `Employee` class.

<box type="success">

Expand All @@ -31,7 +31,7 @@ IntelliJ IDEA provides a refactoring tool that can identify *most* parts of a re

### Assisted refactoring

The `address` field in `Person` is actually an instance of the `seedu.address.model.employee.Address` class. Since removing the `Address` class will break the application, we start by identifying `Address`'s usages. This allows us to see code that depends on `Address` to function properly and edit them on a case-by-case basis. Right-click the `Address` class and select `Refactor` \> `Safe Delete` through the menu.
The `address` field in `Employee` is actually an instance of the `seedu.address.model.employee.Address` class. Since removing the `Address` class will break the application, we start by identifying `Address`'s usages. This allows us to see code that depends on `Address` to function properly and edit them on a case-by-case basis. Right-click the `Address` class and select `Refactor` \> `Safe Delete` through the menu.
* :bulb: To make things simpler, you can unselect the options `Search in comments and strings` and `Search for text occurrences`

![Usages detected](../images/remove/UnsafeDelete.png)
Expand All @@ -40,11 +40,11 @@ Choose to `View Usages` and you should be presented with a list of `Safe Delete

![List of conflicts](../images/remove/SafeDeleteConflicts.png)

Remove usages of `Address` by performing `Safe Delete`s on each entry i.e., double-click on the entry (which takes you to the code in concern, right-click on that entity, and choose `Refactor` -> `Safe delete` as before). You will need to exercise discretion when removing usages of `Address`. Functions like `ParserUtil#parseAddress()` can be safely removed but its usages must be removed as well. Other usages like in `EditPersonDescriptor` may require more careful inspection.
Remove usages of `Address` by performing `Safe Delete`s on each entry i.e., double-click on the entry (which takes you to the code in concern, right-click on that entity, and choose `Refactor` -> `Safe delete` as before). You will need to exercise discretion when removing usages of `Address`. Functions like `ParserUtil#parseAddress()` can be safely removed but its usages must be removed as well. Other usages like in `EditEmployeeDescriptor` may require more careful inspection.

Let’s try removing references to `Address` in `EditPersonDescriptor`.
Let’s try removing references to `Address` in `EditEmployeeDescriptor`.

1. Safe delete the field `address` in `EditPersonDescriptor`.
1. Safe delete the field `address` in `EditEmployeeDescriptor`.

1. Select `Yes` when prompted to remove getters and setters.

Expand All @@ -55,7 +55,7 @@ Let’s try removing references to `Address` in `EditPersonDescriptor`.

<box type="tip" seamless>

**Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Person` class will require you to modify its constructor.
**Tip:** Removing usages may result in errors. Exercise discretion and fix them. For example, removing the `address` field from the `Employee` class will require you to modify its constructor.
</box>

1. Repeat the steps for the remaining usages of `Address`
Expand All @@ -66,13 +66,13 @@ After you are done, verify that the application still works by compiling and run

Unfortunately, there are usages of `Address` that IntelliJ IDEA cannot identify. You can find them by searching for instances of the word `address` in your code (`Edit` \> `Find` \> `Find in path`).

Places of interest to look out for would be resources used by the application. `main/resources` contains images and `fxml` files used by the application and `test/resources` contains test data. For example, there is a `$address` in each `PersonCard` that has not been removed nor identified.
Places of interest to look out for would be resources used by the application. `main/resources` contains images and `fxml` files used by the application and `test/resources` contains test data. For example, there is a `$address` in each `EmployeeCard` that has not been removed nor identified.

![$address](../images/remove/$address.png)

A quick look at the `PersonCard` class and its `fxml` file quickly reveals why it slipped past the automated refactoring.
A quick look at the `EmployeeCard` class and its `fxml` file quickly reveals why it slipped past the automated refactoring.

**`PersonCard.java`**
**`EmployeeCard.java`**

```java
...
Expand All @@ -81,7 +81,7 @@ private Label address;
...
```

**`PersonCard.fxml`**
**`EmployeeCard.fxml`**

``` xml
...
Expand All @@ -99,12 +99,12 @@ At this point, your application is working as intended and all your tests are pa

In `src/test/data/`, data meant for testing purposes are stored. While keeping the `address` field in the json files does not cause the tests to fail, it is not good practice to let cruft from old features accumulate.

**`invalidPersonAddressBook.json`:**
**`invalidEmployeeAddressBook.json`:**

```json
{
"employees": [ {
"name": "Person with invalid name field: Ha!ns Mu@ster",
"name": "Employee with invalid name field: Ha!ns Mu@ster",
"phone": "9482424",
"email": "[email protected]",
"address": "4th street"
Expand Down
28 changes: 14 additions & 14 deletions docs/tutorials/TracingCode.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [

1. Stepping through the method shows that it calls `ArgumentTokenizer#tokenize()` and `ParserUtil#parseIndex()` to obtain the arguments and index required.

1. The rest of the method seems to exhaustively check for the existence of each possible parameter of the `edit` command and store any possible changes in an `EditPersonDescriptor`. Recall that we can verify the contents of `editPersonDesciptor` through the 'Variables' window.<br>
1. The rest of the method seems to exhaustively check for the existence of each possible parameter of the `edit` command and store any possible changes in an `EditEmployeeDescriptor`. Recall that we can verify the contents of `editEmployeeDescriptor` through the 'Variables' window.<br>
![EditCommand](../images/tracing/EditCommand.png)

1. As you just traced through some code involved in parsing a command, you can take a look at this class diagram to see where the various parsing-related classes you encountered fit into the design of the `Logic` component.
Expand All @@ -195,20 +195,20 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
@Override
public CommandResult execute(Model model) throws CommandException {
...
Person employeeToEdit = lastShownList.get(index.getZeroBased());
Person editedEmployee = createEditedPerson(employeeToEdit, editEmployeeDescriptor);
if (!employeeToEdit.isSamePerson(editedEmployee) && model.hasPerson(editedEmployee)) {
throw new CommandException(MESSAGE_DUPLICATE_PERSON);
Employee employeeToEdit = lastShownList.get(index.getZeroBased());
Employee editedEmployee = createEditedEmployee(employeeToEdit, editEmployeeDescriptor);
if (!employeeToEdit.isSameEmployee(editedEmployee) && model.hasEmployee(editedEmployee)) {
throw new CommandException(MESSAGE_DUPLICATE_EMPLOYEE);
}
model.setPerson(employeeToEdit, editedEmployee);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS, editedEmployee));
model.setEmployee(employeeToEdit, editedEmployee);
model.updateFilteredEmployeeList(PREDICATE_SHOW_ALL_EMPLOYEES);
return new CommandResult(String.format(MESSAGE_EDIT_EMPLOYEE_SUCCESS, editedEmployee));
}
```

1. As suspected, `command#execute()` does indeed make changes to the `model` object. Specifically,
* it uses the `setPerson()` method (defined in the interface `Model` and implemented in `ModelManager` as per the usual pattern) to update the employee data.
* it uses the `updateFilteredPersonList` method to ask the `Model` to populate the 'filtered list' with _all_ employees.<br>
* it uses the `setEmployee()` method (defined in the interface `Model` and implemented in `ModelManager` as per the usual pattern) to update the employee data.
* it uses the `updateFilteredEmployeeList` method to ask the `Model` to populate the 'filtered list' with _all_ employees.<br>
FYI, The 'filtered list' is the list of employees resulting from the most recent operation that will be shown to the user immediately after. For the `edit` command, we populate it with all the employees so that the user can see the edited employee along with all other employees. If this was a `find` command, we would be setting that list to contain the search results instead.<br>
To provide some context, given below is the class diagram of the `Model` component. See if you can figure out where the 'filtered list' of employees is being tracked.
<puml src="../diagrams/ModelClassDiagram.puml" width="450" /><br>
Expand Down Expand Up @@ -241,14 +241,14 @@ Recall from the User Guide that the `edit` command has the format: `edit INDEX [
*/
public JsonSerializableAddressBook(ReadOnlyAddressBook source) {
employees.addAll(
source.getPersonList()
source.getEmployeeList()
.stream()
.map(JsonAdaptedPerson::new)
.map(JsonAdaptedEmployee::new)
.collect(Collectors.toList()));
}
```

1. It appears that a `JsonAdaptedPerson` is created for each `Person` and then added to the `JsonSerializableAddressBook`.
1. It appears that a `JsonAdaptedEmployee` is created for each `Employee` and then added to the `JsonSerializableAddressBook`.
This is because regular Java objects need to go through an _adaptation_ for them to be suitable to be saved in JSON format.

1. While you are stepping through the classes in the `Storage` component, here is the component's class diagram to help you understand how those classes fit into the structure of the component.<br>
Expand Down Expand Up @@ -306,6 +306,6 @@ Here are some quick questions you can try to answer based on your execution path
4. Add a new command
5. Add a new field to `Person`
5. Add a new field to `Employee`
6. Add a new entity to the address book

0 comments on commit a06f82c

Please sign in to comment.