-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAddUserStoriesController.java
321 lines (276 loc) · 10.1 KB
/
AddUserStoriesController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
package application;
//import java.net.URL;
//import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
//import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import java.util.ArrayList;
import javafx.collections.FXCollections;
import javafx.scene.control.*;
import javafx.stage.Stage;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class AddUserStoriesController
{
// Maintains reference to the user and stored logs - KW
private Employee user;
private Task task;
private ProjectDataBase projects;
private ArrayList<String> taskNames;
private ArrayList<Task> tasks;
private ArrayList<Integer> estimates;
public Project project;
// Fields for accessType and neededAccess which will be
// Initialized dependent on the user - KW
// private String accessType;
//private String neededAccess;
//Setter methods to collect previous reference to ProjectDataBase/Projects/Tasks - MJ
public void setProjects(ProjectDataBase projects)
{
this.projects = projects;
}
public void setTask(Task task)
{
this.task = task;
//check();
}
public void setProject(Project project)
{
this.project = project;
}
public void setProject(String name)
{
System.out.println(name + " was the name");
//this.project = projects.getProject(name);
}
public void setEstimates(ArrayList<Integer> estimates)
{
this.estimates = estimates;
}
public void setTasks(ArrayList<String> taskNames, ArrayList<Task> tasks)
{
this.taskNames = taskNames;
this.tasks = tasks;
}
public void check()
{
System.out.println(this.project == null);
}
// Fields for the text fields and buttons in the add story stage - KW
@FXML
private TextField userInputStoryField;
@FXML
private Button addUserStoryButton;
@FXML
private ListView<UserStory> userStoryListView;
@FXML
private ComboBox<Integer> fibonacciComboBox;
@FXML
private Button estimateButton;
@FXML
private CheckBox referenceCheckBox;
@FXML
private TextField userInputStoryDescription;
@FXML
private Button submitButton;
@FXML
private Button viewDataButton;
private ArrayList<UserStory> userStories = new ArrayList<>();
private final Integer[] fibonacciNumbers = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
@FXML
private Button back;
// EventHandler for the back button, will take the user back to the
// main menu and pass back the references to the employee and logs - MJ
@FXML
public void goBack(ActionEvent event)
{
try {
FXMLLoader load = new FXMLLoader(getClass().getResource("PlanPokerPane.fxml"));
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
Scene scene = new Scene(load.load());
PlanningPokerController ctrl = load.getController();
ctrl.setAccess(user);
ctrl.setProjects(projects);
ctrl.setTask(task);
ctrl.setProject(project);
ctrl.setEstimates(estimates);
ctrl.setTasks(taskNames, tasks);
ctrl.updateTask(task, estimates.get(taskNames.indexOf(task.name)));
ctrl.setLabel();
stage.setScene(scene);
stage.setTitle("Planning Poker!");
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
//Event handler for when the user presses the View Data button, this opens the Select Project
//page in a new window, to not remove the user from what they are doing - MJ
@FXML
public void viewData(ActionEvent event)
{
try {
FXMLLoader load = new FXMLLoader(getClass().getResource("SelectProject.fxml"));
Stage stage = new Stage();
Scene scene = new Scene(load.load());
SelectProjectController ctrl = load.getController();
ctrl.setAccess(user);
ctrl.setProjects(projects);
ctrl.setFlag('v');
ctrl.setLabel();
ctrl.isSideWindow();
stage.setScene(scene);
stage.setTitle("Project Selection Page!");
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
// Initializes the controller, setting up the ComboBox with Fibonacci numbers - KW
@FXML
public void initialize() {
fibonacciComboBox.setItems(FXCollections.observableArrayList(fibonacciNumbers));
}
// Handles adding a new user story from user input - KW
@FXML
public void handleAddUserStory() {
String userStoryText = userInputStoryField.getText();
String userStoryDescription = userInputStoryDescription.getText();
// Checks if the user story text is not blank before proceeding
if (!userStoryText.isBlank() && !userStoryDescription.isBlank()) {
// Create a UserStory object with both the story, description, and default points
UserStory newUserStory = new UserStory(userStoryText, userStoryDescription, -1);
// Add the UserStory object to the ListView
userStoryListView.getItems().add(newUserStory);
// Clear both input fields for the next entry
userInputStoryField.clear();
userInputStoryDescription.clear();
} else {
// Handle error: Alert the user that the story field is required
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText("Cannot add User Story. Please enter the Story and Description first.");
alert.showAndWait();
}
}
// Sets the estimated points for a selected user story based on Fibonacci numbers - KW
@FXML
public void handleEstimate() {
UserStory selectedStory = userStoryListView.getSelectionModel().getSelectedItem();
if (selectedStory != null && fibonacciComboBox.getValue() != null) {
selectedStory.setPoints(fibonacciComboBox.getValue());
userStoryListView.refresh();
showConfirmationMessage("Estimated story points set to: " + fibonacciComboBox.getValue());
} else {
showErrorMessage("Please select a user story and a Fibonacci number first.");
}
}
// Displays confirmation message when user input handled properly - KW
private void showConfirmationMessage(String message) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Confirmation");
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
// Displays error message when the user makes a mistake - KW
private void showErrorMessage(String message) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
// Handles the submission of user stories, saving them to a CSV file - KW
@FXML
public void handleSubmitButtonAction(ActionEvent event) {
boolean readySubmit = true;
for(int i = 0; i < userStoryListView.getItems().size(); i++)
{
UserStory curr = userStoryListView.getItems().get(i);
if(curr.getPoints() == -1)
{
readySubmit = false;
}
}
if(readySubmit)
{
userStories.clear(); // Clears the existing user stories list to avoid duplicates
userStories.addAll(userStoryListView.getItems());
task.stories = userStories;
saveUserStoriesToCSV(userStories, "userStories.csv"); // Save to CSV
showConfirmationMessage("User stories have been saved.");
int len = userStories.size();
int idx = tasks.indexOf(task);
for(int i = 0; i < len; i++)
{
String name = userStories.get(i).getTitle();
String description = userStories.get(i).getDescription();
int points = userStories.get(i).getPoints();
task.addStory(name, description, points);
}
tasks.set(idx, task);
try {
FXMLLoader load = new FXMLLoader(getClass().getResource("PickCard.fxml"));
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
Scene scene = new Scene(load.load());
PickCardController ctrl = load.getController();
ctrl.setAccess(user);
ctrl.setProjects(projects);
ctrl.setProject(project);
ctrl.setTask(task);
ctrl.setEstimates(estimates);
ctrl.setTasks(taskNames, tasks);
ctrl.setLabel();
stage.setScene(scene);
stage.setTitle("Pick a card!");
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
showErrorMessage("Please configure all estimates before submitting!");
}
}
// Saves a list of UserStory objects to a specified CSV file
private void saveUserStoriesToCSV(List<UserStory> userStories, String filename) {
try (FileWriter writer = new FileWriter(filename)) {
// Writing header
writer.write("Title,Description,Points\n");
for (UserStory story : userStories) {
writer.write(convertToCSV(story) + "\n");
}
} catch (IOException e) {
showErrorMessage("Error writing to CSV file: " + e.getMessage());
}
}
// Method for to prevent special character errors - KW
private String convertToCSV(UserStory story) {
// Using the UserStory methods getTitle(), getDescription(), and getPoints()
// Handles any special characters, like commas in titles or descriptions
return escapeSpecialCharacters(story.getTitle()) + ","
+ escapeSpecialCharacters(story.getDescription()) + ","
+ story.getPoints();
}
// Method for to prevent special character errors - KW
private String escapeSpecialCharacters(String data) {
String escapedData = data.replaceAll("\\R", " "); // Replace newlines with spaces
if (data.contains(",") || data.contains("\"") || data.contains("\n")) {
data = data.replace("\"", "\"\""); // Replace quotes with double quotes
escapedData = "\"" + data + "\""; // Quote the entire field
}
return escapedData;
}
// Method to establish access to maintain reference to user - MJ
public void setAccess(Employee empType)
{
user = empType;
}
}