3030import java .time .format .DateTimeParseException ;
3131import java .time .format .FormatStyle ;
3232import java .util .*;
33+ import java .util .function .Consumer ;
3334import java .util .stream .Collectors ;
3435
3536@ Component
@@ -104,6 +105,8 @@ public void initForDate(LocalDate currentReportDate, List<Work> currentWorkItems
104105 Optional <HeimatTime > optionalAlreadyBookedTime = Optional .empty ();
105106 if (optionalHeimatMapping .isPresent ()) {
106107 isMappedInHeimat = true ;
108+ // TODO possibly there is more than one already booked time!
109+ // TODO there might be more than one KeepTime project assigned to HEIMAT project
107110 optionalAlreadyBookedTime = heimatTimes .stream ()
108111 .filter (heimatTime -> heimatTime .taskId ()
109112 == optionalHeimatMapping .get ().getExternalTaskId ())
@@ -183,6 +186,15 @@ protected void updateItem(Project item, boolean empty) {
183186 TableColumn <TableRow , TableRow > timeColumn = new TableColumn <>("Time" );
184187 timeColumn .setCellValueFactory (data -> new SimpleObjectProperty <>(data .getValue ())); // Placeholder property
185188
189+ Consumer <Spinner <LocalTime >> spinnerValid = (Spinner <LocalTime > spinner ) -> {
190+ int seconds = spinner .getValue ().toSecondOfDay ();
191+ int minutes = (seconds / 60 );
192+ if (seconds != 0 || minutes % 15 != 0 || minutes <= 0 ) {
193+ spinner .setStyle ("-fx-border-color: red; -fx-border-width: 2px; -fx-border-radius: 4px;" );
194+ } else {
195+ spinner .setStyle ("" ); // Reset to default style
196+ }
197+ };
186198 timeColumn .setCellFactory (column -> new TableCell <>() {
187199 private final Spinner <LocalTime > timeSpinner = new Spinner <>();
188200 private final Label keeptimeLabel = new Label ();
@@ -210,7 +222,9 @@ protected void updateItem(TableRow item, boolean empty) {
210222 timeSpinner .getValueFactory ().setValue (LocalTime .ofSecondOfDay (item .userTimeSeconds .get ()));
211223 localTimeChangeListener = (observable , oldValue , newValue ) -> {
212224 item .userTimeSeconds .set (newValue .toSecondOfDay ());
225+ spinnerValid .accept (timeSpinner );
213226 };
227+ spinnerValid .accept (timeSpinner );
214228 timeSpinner .valueProperty ().addListener (localTimeChangeListener );
215229 setGraphic (container );
216230 }
@@ -221,6 +235,13 @@ protected void updateItem(TableRow item, boolean empty) {
221235 TableColumn <TableRow , TableRow > notesColumn = new TableColumn <>("Notes" );
222236 notesColumn .setCellValueFactory (data -> new SimpleObjectProperty <>(data .getValue ())); // Placeholder property
223237
238+ Consumer <TextArea > textAreaValid = (TextArea textArea ) -> {
239+ if (textArea .getText ().isBlank ()) {
240+ textArea .setStyle ("-fx-border-color: red; -fx-border-width: 2px; -fx-border-radius: 4px;" );
241+ } else {
242+ textArea .setStyle ("" ); // Reset to default style
243+ }
244+ };
224245 notesColumn .setCellFactory (column -> new TableCell <>() {
225246 private ChangeListener <String > stringChangeListener ;
226247 private final TextArea textArea = new TextArea ();
@@ -232,7 +253,6 @@ protected void updateItem(TableRow item, boolean empty) {
232253 textArea .setPrefHeight (50 );
233254 textArea .setPrefWidth (100 );
234255 textArea .setWrapText (true );
235- // TODO mark textArea red when not content
236256 // TODO make it possible to copy content of heimatNotesLabel
237257 hbox .getChildren ().addAll (new Label ("Heimat:" ), heimatNotesLabel );
238258 container .getChildren ().addAll (textArea , hbox );
@@ -247,7 +267,11 @@ protected void updateItem(TableRow item, boolean empty) {
247267 setGraphic (null );
248268 } else {
249269 textArea .setText (item .keeptimeNotes .get ());
250- stringChangeListener = (obs , oldText , newText ) -> item .userNotes .set (newText );
270+ stringChangeListener = (obs , oldText , newText ) -> {
271+ item .userNotes .set (newText );
272+ textAreaValid .accept (textArea );
273+ };
274+ textAreaValid .accept (textArea );
251275 textArea .textProperty ().addListener (stringChangeListener );
252276 heimatNotesLabel .setText (item .heimatNotes .get ());
253277 setGraphic (container );
@@ -352,6 +376,8 @@ public void increment(final int steps) {
352376
353377 public static LocalTime decrementToLastFullQuarter (LocalTime time ) {
354378 int minutes = time .getMinute ();
379+ if (minutes == 0 )
380+ return time ; // don't decrement below 0
355381 int decrement = (minutes % 15 == 0 && time .getSecond () == 0 ) ? 15 : minutes % 15 ;
356382 return time .minusMinutes (decrement ).withSecond (0 ).withNano (0 );
357383 }
0 commit comments