Merge branch 'main' of gitlab.ewi.tudelft.nl:cse1105/2025-2026/teams/csep-team-76 into feature/client_config

This commit is contained in:
Rithvik Sriram 2025-11-28 00:29:58 +01:00
commit e8a7b03874
6 changed files with 527 additions and 34 deletions

View file

@ -0,0 +1,192 @@
package client.scenes;
import java.util.List;
import commons.Recipe;
import jakarta.inject.Inject;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
public class OverviewCtrl {
private final MainCtrl mainCtrl;
// all of these aren't used with only my part of the code
// everything in the top bar ===
@FXML
private Button flagEnButton; //already here for advanced stuff
@FXML
private Button flagNlButton; //already here for advanced stuff
@FXML
private Button flagPlButton; //already here for advanced stuff
@FXML
private Button refreshButton;
@FXML
private Button closeButton; //already here for advanced stuff
@FXML
private Button maximizeButton; //already here for advanced stuff
@FXML
private Button minimizeButton; //already here for advanced stuff
// everything in the left lane
@FXML
private ListView<Recipe> recipeList;
@FXML
private Button addRecipeButton;
@FXML
private Button removeRecipeButton;
// === CENTER: RECIPE DETAILS ===
@FXML
private Label recipeNameLabel;
@FXML
private Button editRecipeTitleButton;
@FXML
private ListView<String> ingredientsListView;
@FXML
private Button addIngredientButton;
@FXML
private ListView<String> preparationListView;
@FXML
private Button addPreparationStepButton;
@Inject
public OverviewCtrl(MainCtrl mainCtrl) {
this.mainCtrl = mainCtrl;
}
@FXML
private void initialize() {
// Show recipe name in the list
recipeList.setCellFactory(list -> new ListCell<>() {
@Override
protected void updateItem(Recipe item, boolean empty) {
super.updateItem(item, empty);
setText(empty || item == null ? "" : item.getName());
}
});
// When your selection changes, update details in the panel
recipeList.getSelectionModel().selectedItemProperty().addListener(
(obs, oldRecipe, newRecipe) -> showRecipeDetails(newRecipe)
);
// Double-click to go to detail screen
recipeList.setOnMouseClicked(event -> {
final int DOUBLE_CLICK = 2; //to not get magic number:P
if (event.getClickCount() == DOUBLE_CLICK) {
openSelectedRecipe();
}
});
refresh();
}
// till the all the code from everyone is implemented for now to not have errors
private void showRecipeDetails(Recipe newRecipe) {
}
// Button handlers
@FXML
private void refresh() {
// TODO: someone else doing this
List<Recipe> recipes = showRecipeDetails();
recipeList.getItems().setAll(recipes);
// Select first recipe in the list by default
if (!recipes.isEmpty()) {
recipeList.getSelectionModel().selectFirst();
}
}
// to remove error till everything else is implemented
private List<Recipe> showRecipeDetails() {
return List.of();
}
@FXML
private void addRecipe() {
// Navigate to "create recipe" screen (should be like a pop-up or new screen or just another place in the app)
mainCtrl.showOverview();
}
@FXML
private void removeSelectedRecipe() {
Recipe selected = recipeList.getSelectionModel().getSelectedItem();
if (selected == null) {
return;
}
// TODO: someone else todo
recipeList.getItems().remove(selected);
showRecipeDetails(null);
}
@FXML
private void openSelectedRecipe() {
Recipe selected = recipeList.getSelectionModel().getSelectedItem();
if (selected == null) {
return;
}
// Let MainCtrl open the full detail screen
mainCtrl.showOverview(); //I had showrecipedetail but intelij says showoverview
}
@FXML
private void editRecipeTitle() {
// TODO: someone else todo
// For now reuse openSelectedRecipe()
openSelectedRecipe();
}
@FXML
private void addIngredient() {
// TODO: make it possible to add ingredient to current recipe
System.out.println("Add ingredient clicked");
}
@FXML
private void addPreparationStep() {
// TODO: make it possible to add step to current recipe
System.out.println("Add preparation step clicked");
}
// Language buttons
@FXML
private void switchToEnglish() {
System.out.println("Switch language to EN");
}
@FXML
private void switchToDutch() {
System.out.println("Switch language to NL");
}
@FXML
private void switchToPolish() {
System.out.println("Switch language to PL");
}
}

View file

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<BorderPane prefHeight="800.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.scenes.OverviewCtrl">
<!-- TOP BAR -->
<top>
<HBox spacing="10">
<padding>
<Insets bottom="10" left="10" right="10" top="10" />
</padding>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="198.0" minWidth="10.0" prefWidth="130.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="2.0" prefWidth="70.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="54.0" minHeight="10.0" prefHeight="54.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="25.0" minHeight="6.0" prefHeight="6.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label prefHeight="56.0" prefWidth="158.0" text="FoodPal">
<font>
<Font name="System Bold" size="29.0" />
</font>
</Label>
<ButtonBar prefHeight="40.0" prefWidth="200.0" GridPane.rowIndex="2">
<buttons>
<ToolBar prefHeight="35.0" prefWidth="123.0">
<items>
<Button fx:id="flagEnButton" minWidth="33.0" onAction="#switchToEngelish" prefHeight="25.0" prefWidth="33.0" text="EN" />
<Button fx:id="flagNlButton" onAction="#switchToDutch" text="NL" />
<Button fx:id="flagPlButton" onAction="#switchToPolish" text="PL" />
</items>
</ToolBar>
</buttons>
</ButtonBar>
</children>
</GridPane>
<Pane HBox.hgrow="ALWAYS" />
<HBox spacing="5" />
<GridPane prefHeight="90.0" prefWidth="114.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="315.0" minWidth="10.0" prefWidth="32.1666259765625" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="315.0" minWidth="10.0" prefWidth="24.8333740234375" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="173.0" minWidth="10.0" prefWidth="28.6666259765625" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="34.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button fx:id="closeButton" onAction="#closeWindow" text="X" GridPane.columnIndex="3" />
<Button fx:id="maximizeButton" onAction="#MazimizeWindow" text="□" GridPane.columnIndex="2" />
<Button fx:id="minimizeButton" onAction="#MinimizeWindow" text="-" GridPane.columnIndex="1" />
<Button fx:id="refreshButton" onAction="#refresh" prefHeight="25.0" prefWidth="34.0" text="⟳" GridPane.columnIndex="3" GridPane.rowIndex="2" />
</children>
</GridPane>
</HBox>
</top>
<!-- LEFT: RECIPE LIST -->
<left>
<VBox spacing="10">
<padding>
<Insets bottom="10" left="10" right="10" top="10" />
</padding>
<Label text="Recipes">
<font>
<Font name="System Bold" size="15.0" />
</font></Label>
<ListView fx:id="recipeList" />
<HBox spacing="10">
<Button fx:id="AddRecipeButton" onAction="#addRecipe" text="Add Recipe" />
<Button fx:id="RemoveRecipeButton" onAction="#removeSelectedRecipe" text="Remove Recipe" />
<Button mnemonicParsing="false" text="Clone" />
</HBox>
</VBox>
</left>
<!-- CENTER: RECIPE DETAILS -->
<center>
<VBox spacing="20">
<padding>
<Insets bottom="10" left="10" right="10" top="10" />
</padding>
<!-- Recipe title row -->
<HBox spacing="10">
<Label fx:id="replaceNameLabel" text="Recipe Name">
<font>
<Font name="System Bold" size="14.0" />
</font></Label>
<Button fx:id="editRecipeTitleButton" onAction="#editRecipeTitle" text="Edit" />
<Button fx:id="RemoveRecipeButton2" mnemonicParsing="false" onAction="#removeSelectedRecipe" text="Remove Recipe" />
<Button fx:id="printRecipe" mnemonicParsing="false" onAction="#MakePrintable" text="Print Recipe" />
</HBox>
<!-- Ingredients -->
<VBox spacing="10">
<Label fx:id="ingredientsListView" text="Ingredients">
<font>
<Font name="System Bold" size="14.0" />
</font></Label>
<ListView prefHeight="167.0" prefWidth="912.0" />
<Button fx:id="addIngredientButton" onAction="#addIngredient" text="Add Ingredient" />
</VBox>
<!-- Preparation -->
<VBox spacing="10">
<Label fx:id="preparationListView" text="Preparation">
<font>
<Font name="System Bold" size="14.0" />
</font></Label>
<ListView prefHeight="200.0" />
<Button fx:id="addPreparationStepButton" onAction="#addPreperationStep" text="Add Step" />
</VBox>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="890.6666870117188" minWidth="10.0" prefWidth="854.6666870117188" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="445.3333740234375" minWidth="10.0" prefWidth="57.33331298828125" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</VBox>
</center>
</BorderPane>

View file

@ -1,46 +1,62 @@
# Code of Conduct CSEP
> Last changed: 2025-11-14 04:20 PM
## Assignment description
- working on our teamwork skills
- coding with other people
- communication skill in a group setting
> Last changed: 2025-11-27 10:30 PM
## 1. Assignment description
- Working on our teamwork skills by helping and collaborating with each other.
- Coding with other people through the use of Git + GitLab tooling.
- Communication skill in a group setting working in a project with 6 people
## Target or ambition level
- so we working towards a 10 but a 8 is fine
- the most important thing is that everyone does their best
## 2. Target or ambition level
- Goal is at least an 8/10, aiming for a 10.
- The most important thing is that everyone does their best
## Planning
- friday - before the ta meeting checking eachother codes and making a planning for the week after
- label the to do lists in gitlab on friday (during planning time)
- check up on eachother thoughout the week
- **Submitter** - Rithvik
## 3. Planning
- Meet in person minimally 2 times a week with preference to Thursday and Friday
- Meet 1 time a week online on monday
- We will adjust expectations and deadlines dynamically depending on what has been actually achieved in the previous week, during one of the aforementioned meetings.
- During a pre-meeting session in the CSE1105 labs on Friday, we will:
- discuss any development blockages that team members encountered during the week.
- go over open MRs.
- plan any task items for the next week.
- consider potential additions to the week's agenda.
- **Submitter of any Brightspace material** - Rithvik Sriram
## Communication
- Discord for our online meeting and sharing info and asking questions
## 4. Communication
- Discord for our online meeting and sharing info and asking questions.
- GitLab to share our code
- Friday lab meetings for in person meetings
- Thursday and Friday lab meetings for in person meetings
### Collaboration outside of the mandatory meetings
- Friday during lab before ta meeting
- Discord
## 5. Collaboration outside of the mandatory meetings
- Thursdays (to code together and help eachother)
- Friday during lab before ta meeting (to make the final changes before merging)
- Discord (for our quick questions about the small things)
- GitLab
## Help and assistance
- We have discord together, so if there is a question or issue it can be asked there and also during the friday meeting
## 6. Help and assistance
- Reserving Discord as a method of communication through which anyone who has an issue or question can talk.
- A person who is having trouble with implementing a specific part of the software is ensured to have another team member available who can assist in debugging/guiding the implementation of that particular feature.
## Work quality
- By having the other 5 members rate the code on gitlab
- Making sure we use the same checkstyle document
## 7. Work quality
- Each Merge Request is required to:
- have at least approval from one person responsible for backend, and one person responsible for frontend.
- concern only one feature/issue, to ensure atomic MRs/commits.
- have generally atomic commits, aka. frequent and small, such that any issues introduced by one specific commit can be triaged quickly.
- Comply to the existing CheckStyle document (enforced automatically via Maven build server).
- have clear comments and JavaDoc written wherever non-trivial functionality is involved.
## Decision-making
- Discuss it with arguments so consensus
## 8. Decision-making
- Important decisions within the group, such as major refactoring or design decisions, will be decided within the group by way of consensus.
- Decide on where and where to meet during the week by way of Discord polling.
## Broken agreements
- Discuss it with them
- If they dont do anything (work, meetings) at all discuss with the ta
## 9. Broken agreements
- If someone breaks the agreements we have agreed upon in this code of conduct we will first of all discuss it with them
- If someone isn't collaborating at all we will make this clear to the TA and hope they can help
- If that doesn't resolve it we will bring it up with the lecturer
- Never will we just exclude someone without taking the proper step
## 10. Problem resolution
- Main way of problem resolution is by reasoning and team discussion in good faith.
- If a team member is not able to, or will be late to, a specific meeting, this should be communicated at least 1 full day before the meeting's commencement.
- For major issues and problems for which the above methods cannot suffice, the responsible chair during the week in which the issue occurred will consult third parties in order of increasing severity:
1. discuss the issue with the TA.
2. communicate with the CSE1105 teaching team e.g. by form of email.
## Problem resolution
- We are all adults here so we can just talk it out by civil discussion
- If your gonna be late, communicate with the rest of the team
- Give a reason if you can't show up for a meeting
- Contact with the TA will be needed when someone doesn't react to any of our messages and doesnt show up at all

42
countlines.bat Normal file
View file

@ -0,0 +1,42 @@
@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('git config user.email') do set AUTHOR=%%i
echo Checking commit stats for %AUTHOR%...
echo.
echo === Last 7 days (all .java files) ===
git log --author="%AUTHOR%" --since="7 days ago" --pretty=tformat: --numstat | findstr "\.java" > temp_java.txt
set added=0
set removed=0
for /f "tokens=1,2" %%a in (temp_java.txt) do (
set /a added+=%%a
set /a removed+=%%b
)
set /a net=added-removed
echo Lines added in .java: %added%
echo Lines removed in .java: %removed%
echo Net lines: %net%
echo.
echo === All time (excluding *Test.java) ===
git log --author="%AUTHOR%" --pretty=tformat: --numstat -- . ":(exclude)*Test.java" | findstr "\.java" > temp_java.txt
set added=0
set removed=0
for /f "tokens=1,2" %%a in (temp_java.txt) do (
set /a added+=%%a
set /a removed+=%%b
)
set /a net=added-removed
echo Lines added in .java (excluding *Test.java): %added%
echo Lines removed in .java (excluding *Test.java): %removed%
echo Net lines: %net%
del temp_java.txt
endlocal

28
countlines.sh Normal file
View file

@ -0,0 +1,28 @@
#!/bin/bash
AUTHOR=$(git config user.email)
echo -e "Checking commit stats for \033[38:5:2m$AUTHOR\033[0m..."
# Get numstat for commits by author, filter only .java lines
git log --author="$AUTHOR" --since="7 days ago" --pretty=tformat: --numstat \
| awk '
$3 ~ /\.java$/ {
added += $1
removed += $2
}
END {
print "Lines added in .java:", added
print "Lines removed in .java:", removed
print "Net lines:", added - removed
}'
git log --author="$AUTHOR" --pretty=tformat: --numstat -- . ':(exclude)*Test.java' \
| awk '
$3 ~ /\.java$/ {
added += $1
removed += $2
}
END {
print "Lines added in .java (excluding *Test.java):", added
print "Lines removed in .java (excluding *Test.java):", removed
print "Net lines:", added - removed
}'

59
docs/agenda/agenda-03.md Normal file
View file

@ -0,0 +1,59 @@
# Week 3 meeting agenda
| Key | Value |
| ------------ | -------------------------------------------------------- |
| Date | Nov 28th |
| Time | 16:45 |
| Location | DW PC Hall 2 |
| Chair | Steven Liu |
| Minute Taker | Oskar Rasieński |
| Attendees | Mei Chang van der Werff, Natalia Cholewa, Rithvik Sriram |
## Table of contents
1. (1 min) Introduction by chair
2. (1 min) Any additions to the agenda?
3. (1-2 min) TA announcements?
4. (1-2 min) New submission of Code of Conduct + additions?
5. (30 min) **Meeting content**
1. (2 min) Week 3 progress checklist, MRs, and summary
- Have we completed all of basic requirements? If not, what to resolve as soon as possible.
2. (3 min) Socket modelling - what do we (don't) want to update with WebSockets
1. How should we model individual changes, e.g. what happens when the user adds a new recipe? or add an ingredient to a recipe?
3. (3 min) Discussion on implementing nutritional value calculations
4. (1-2 min) Questions and/or suggestions
5. (20 min) **Sprint planning week 4**
1. (2-3 min) Set a provisional deadline for completing parts of the backlog
2. (2 min) Confirm week 4 backend/frontend team formation
3. (5 min) Tasks creation (GitLab) and assignment
4. (5 min) Decide on a TODO list that each team should complete before the next meeting (see below for a provisional proposal)
5. (5 min) Other issues
6. (2 min) Questions
**Max time:** ~35 minutes
## Addendum
### Provisional week 3 tasks checklist
> May have further additions after the pre-meeting session.
**Backend**:
- [ ] Basic recipe definition
- [ ] API endpoints that provide Recipe CRUD functionality
- [ ] Unit tests for the endpoints
- [ ] ...
**Frontend**:
- [ ] A list of recipe names to choose from
- [ ] An interface to display a recipe when it is chosen from the recipe list
- [ ] (Functional) buttons in the interface
- [ ] Abstracted requests sending to the backend
- [ ] ...
## Provisional week 4 list of tasks
**Backend**:
- 4.2 content
- WebSockets service implementation
- 4.3 content
- implementing actual formal/informal ingredients and appropriate unit class definitions
- ... more to add
**Frontend**:
- Make sure the basic frontend functionality are in place and works as expected
- Improving ingredient/steps editing + deletion to work with the new Ingredient and Unit types
- Making a new scene/view + buttons for the Nutrition view
- Make the interface text ResourceBundle based to implement internationalisation
- ... more to add