Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
393dd55
#178: fix issue when task is no longer available for a present time. …
Death111 May 14, 2025
6d6431e
PTBAS-738: Adjust sync window
MomdAli Sep 9, 2025
f4a0b09
PTBAS-738: Improve styling
MomdAli Sep 10, 2025
ccb8a5a
PTBAS-738: Combine SearchField and Button into one ComboBox
MomdAli Sep 10, 2025
8254c79
PTBAS-738: Improve SearchPopup compatibilty for feature uses
MomdAli Sep 10, 2025
1f7505f
PTBAS-741: MappingDialog tooltips, search, and mapping deletion options
MomdAli Sep 12, 2025
5b016a7
PTBAS-742: Refactor Heimat name and update README
MomdAli Sep 15, 2025
f8038c5
PTBAS-741: Implement test on duplicate entry bug
MomdAli Sep 15, 2025
2ca3567
PTBAS-742: Add 7 day log cap
MomdAli Sep 15, 2025
a51b437
PTBAS-741: Add new images and improve README
MomdAli Sep 18, 2025
fd527bd
Revert "PTBAS-741: Add new images and improve README"
MomdAli Sep 19, 2025
2ab76c0
PTBAS-742: Add new images and improve README
MomdAli Sep 18, 2025
a039e84
PTBAS-742: Fix image width
MomdAli Sep 19, 2025
a381992
setting locale to english on startup. keeping system locale for conve…
Death111 Oct 20, 2025
7793cf3
apply formatter
Death111 Oct 20, 2025
9270aec
Merge pull request #183 from doubleSlashde/feature/#178_heimatIntegra…
Death111 Oct 20, 2025
2bd263d
PTBAS-738: replace TextFlow element in business logic with custom Sty…
Death111 Oct 20, 2025
a120e8c
PTBAS-738: only register one keylistener for all spinners
Death111 Oct 20, 2025
f4ec870
PTBAS-738: inline variable
Death111 Oct 20, 2025
d2eaa49
PTBAS-738: set tooltup directly during label creation. rename, comments
Death111 Oct 20, 2025
5b07c3d
Merge branch 'develop' into feature/PTBAS-738_syncDialogAnpassungen
Death111 Oct 20, 2025
e51e25d
PTBAS-738: fix element not present error for booking hint. also show …
Death111 Oct 20, 2025
c9bc4ea
PTBAS-738: Refactor SearchPopup into SearchCombobox and remove unnece…
MomdAli Oct 23, 2025
2d0f68d
Merge pull request #191 from doubleSlashde/bugfix/PTBAS-737_consisten…
Death111 Oct 23, 2025
661f71a
PTBAS-738: fix tests
Death111 Oct 23, 2025
b6ded44
Merge pull request #185 from doubleSlashde/feature/PTBAS-738_syncDial…
Death111 Oct 23, 2025
6fbccae
Merge branch 'develop' into feature/PTBAS-741_mappingDialogAdjustment
Death111 Oct 23, 2025
87cf1c3
PTBAS-741: Fix issues
MomdAli Nov 21, 2025
58855e0
#194: Add Fedora Workstation 43 to tested OSs
mplieske Nov 25, 2025
05925f9
Merge pull request #195 from doubleSlashde/feature/#194_add_fedora_to…
Death111 Dec 2, 2025
f379d52
PTBAS-742: Update README for Heimat integration and change settings t…
MomdAli Dec 11, 2025
b49d461
use link to heimat website
Death111 Apr 6, 2026
5443729
use upper case spelling for menu selection
Death111 Apr 6, 2026
65b0f1d
Merge branch 'develop' into chore/PTBAS-742_heimatNameRefactoring
Death111 Apr 6, 2026
513bb88
PTBAS-742: move heimat readme in custom readme file.
Death111 Apr 6, 2026
33ee940
PTBAS-742: lower size cap from 3gb to 10mb
Death111 Apr 6, 2026
07419a7
Merge pull request #187 from doubleSlashde/chore/PTBAS-742_heimatName…
Death111 Apr 6, 2026
6dd8a8a
PTBAS-741: remove heimatExpiresLabel
Death111 Apr 6, 2026
bfbe8d8
Merge branch 'develop' into feature/PTBAS-741_mappingDialogAdjustment
Death111 Apr 6, 2026
bad0ec3
PTBAS-741: add test which reproduced issue previous version
Death111 Apr 6, 2026
0dbbcac
PTBAS-741: try revert heimat controller regaring duplicate row bug an…
Death111 Apr 6, 2026
5f40787
PTBAS-741: highlight invalid mappings in ui. only pass actually avail…
Death111 Apr 6, 2026
653e503
PTBAS-741: show the invalid mappings on platform.runLater again
Death111 Apr 6, 2026
28523d6
PTBAS-741: fix jwt expiration logic
Death111 Apr 6, 2026
0af5594
PTBAS-741: allow "null" as value as well for searchCombobox
Death111 Apr 6, 2026
03e29d8
#188: add work entry
Death111 Apr 6, 2026
51ff7de
#188: move add button to the right. add plus icon.
Death111 Apr 6, 2026
31eff20
PTBAS-741: add tests for invalid mapping logic. format files
Death111 Apr 15, 2026
372d34a
Merge pull request #186 from doubleSlashde/feature/PTBAS-741_mappingD…
Death111 Apr 15, 2026
df965a9
Merge pull request #201 from doubleSlashde/feature/#188_addManualTask…
Death111 Apr 15, 2026
b05cf6f
fix typo
Death111 Apr 28, 2026
bca9f0c
use "keep" as default in mapping dialog for invalid projects
Death111 Jun 4, 2026
e7bb651
disable sync if no project is selected to be synced
Death111 Jun 4, 2026
d24d143
show count of projects which will be synced on sync-button
Death111 Jun 4, 2026
c0cd4d0
when changing a time, the project is enabled for sync now
Death111 Jun 4, 2026
997eb0a
bat now validates if java and .jar can be found. shows error if not
Death111 Jun 4, 2026
03a52e6
Merge pull request #202 from doubleSlashde/feature/smallImprovements
Death111 Jun 4, 2026
9067dcd
update dependencies. remove sonar step in pipeline
Death111 Jun 4, 2026
3855529
overwrite tomcat to patched version
Death111 Jun 4, 2026
8157997
overwrite tomcat to patched version (websocket as well)
Death111 Jun 4, 2026
4f72a54
Merge pull request #203 from doubleSlashde/feature/updateDependencies
Death111 Jun 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .github/workflows/mavenCi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ jobs:
name: KeepTime-${{ env.version }}
path: /home/runner/work/KeepTime/KeepTime/target/*-bin.zip

- name: Analyze
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn -V -B sonar:sonar -Dsonar.host.url=${{ secrets.HOST_URL }} -Dsonar.organization=${{ secrets.ORGANIZATION_NAME }} -Dsonar.projectKey=${{ secrets.PROJECT_KEY }} -Dsonar.java.binaries=. -Dsonar.qualitygate.wait=false

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3

Expand Down
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Application to track your time spent on different projects each day. Aim was to

Create projects and choose if they are counted as 'work time'. Select the project you work on. Before you switch the project, write a comment on what u did. Change the project. Repeat.

KeepTime can connect to [Heimat](https://heimat-software.com/) so you can import Heimat projects and sync your tracked time back to Heimat. Details: [heimat.md](readme/heimat.md).

## Usage

### Main view:
Expand All @@ -29,9 +31,25 @@ Create projects and choose if they are counted as 'work time'. Select the projec
+ Export: export database for backup and later import (import currently not yet implemented)

### Reports:
![Report Screen](readme/images/reportDescription.png?raw=true "Report")

+ the report screen gives you a summary for every day
KeepTime’s reporting workflow works by tracking daily work and synchronizing project activities with external task management. Here’s how you use it:

1. **Track Your Work**
Throughout your workday, log activities and assign them to projects. Each entry includes a timeslot, duration, and optional notes.

2. **Review Your Daily Report**
At any time, open the report view to see an overview of your day, including all logged activities, their durations, and project associations.

3. **Edit and Manage Entries**
Use the controls in the report to copy, edit, or delete individual work entries as needed. You can also copy notes or summaries for external use.

4. **Select the Day to View**
Use the calendar widget to select which day’s report you want to review. Only days with recorded work are available.

5. **Synchronize Projects with Heimat**
If you want you can syncronize the current date with Heimat. See [heimat.md](readme/heimat.md)

![Report Dialog](readme/images/reportDescription.png)

## Install

Expand Down Expand Up @@ -73,6 +91,6 @@ You should put the .jar in an extra folder as a *logs* and a *db* folder will be
## Requirements
* Operating System
* Windows 7, 10, 11
* Linux (tested on Ubuntu 18.04)
* Linux (tested on Ubuntu 18.04, Fedora Workstation 43)
* Mac (tested on MacBook M2 Pro (ARM based CPU))
* Java >= 17
28 changes: 27 additions & 1 deletion keeptime.bat
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
start "" "javaw" -Dprism.order=sw -jar keeptime.jar
@echo off
setlocal

cd /d "%~dp0"

where javaw >nul 2>&1
if errorlevel 1 (
echo ERROR: Java was not found.
echo.
echo Please install Java.
echo See installation requirements: https://github.com/doubleSlashde/KeepTime#requirements
echo.
pause
exit /b 1
)

if not exist "keeptime.jar" (
echo ERROR: keeptime.jar was not found in this folder.
echo.
echo Please download and extract KeepTime from the releases page.
echo See installation instructions: https://github.com/doubleSlashde/KeepTime#install
echo.
pause
exit /b 1
)

start "" "javaw" -Dprism.order=sw -jar keeptime.jar
34 changes: 20 additions & 14 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<version>3.5.14</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>
Expand Down Expand Up @@ -39,7 +39,7 @@
<java.version>17</java.version>
<javafx.version>22</javafx.version>

<maven-dependency-check.version>12.0.1</maven-dependency-check.version>
<maven-dependency-check.version>12.2.2</maven-dependency-check.version>
<!-- USING HTML,XML (comma-separated list) did not work with plugin version 5.1.0 -->
<maven-dependency-check.format>ALL</maven-dependency-check.format>
<maven-dependency-check.failOnError>true</maven-dependency-check.failOnError>
Expand Down Expand Up @@ -103,7 +103,18 @@
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.5</version>
<version>2.8.17</version>
</dependency>
<!-- Overwrite tomcat version due to security vulnerability. remove when possible -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>10.1.55</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>10.1.55</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -147,14 +158,9 @@
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.7.1</version>
<version>3.8.0</version>
<type>maven-plugin</type>
</dependency>
<dependency>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.11.0.3922</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
Expand All @@ -165,7 +171,7 @@
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.2</version>
<version>2.22.0</version>
</dependency>

</dependencies>
Expand Down Expand Up @@ -208,7 +214,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
<version>3.22.0</version>
</plugin>

<!-- https://mvnrepository.com/artifact/org.owasp/dependency-check-maven (run with mvn dependency-check:check ) -->
Expand Down Expand Up @@ -267,21 +273,21 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.15.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
<version>1.6.3</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<version>0.8.14</version>
<executions>
<execution>
<id>prepare-agent</id>
Expand Down
53 changes: 53 additions & 0 deletions readme/heimat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Heimat integration

[Heimat](https://heimat-software.com/) is external project and time-tracking software. KeepTime can connect to it so you can:

- **Import** projects from Heimat into KeepTime, or **link** Heimat projects to projects you already have in KeepTime.
- **Push** the time you logged in KeepTime for a given day into Heimat when you choose to sync.

**Important:** KeepTime never writes to Heimat on its own. Data is sent to Heimat only when you run the sync from the report view.

---

## 1. Connect KeepTime to Heimat

1. Open **Settings** and go to the **HEIMAT** section.

![Settings Heimat](images/settingsHeimat.png "Settings Heimat")

2. Fill in:

| Field | What to enter |
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| **URL** | Your Heimat instance URL (the same base URL you use in the browser), for example `https://your-company.example.com`. |
| **Access token** | Create or copy a token in Heimat (under your account or API settings) and paste it here. |

![Heimat Website](images/heimatWebsite.png "Heimat Website")

3. Click **Validate connection**. If it succeeds, the integration is ready to use.

---

## 2. Match Heimat projects to KeepTime

After a successful connection, use **Map projects** (button in Heimat settings dialog) to either:

- Map each Heimat project to an existing KeepTime project, or
- Import Heimat projects as new KeepTime projects.

Do this once (or whenever your project lists change) so KeepTime knows where each Heimat project should go.

---

## 3. Sync a day’s work to Heimat

When you want to upload time for the **currently selected day** in the report:

1. Open the **report** view for that day.
2. Click the **sync** button (Heimat / external sync).
3. In the dialog, choose which projects to include and add any **note** you want stored with the sync.
4. Click **Sync** to send that day’s tracked time to Heimat.

![External Project Dialog](images/externalProjectDialog.png)

Until you complete step 4, nothing is written to Heimat.
Binary file added readme/images/externalProjectDialog.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 added readme/images/heimatWebsite.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 readme/images/reportDescription.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 added readme/images/settingsHeimat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 23 additions & 2 deletions src/main/java/de/doubleslash/keeptime/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.StringWriter;
import java.time.LocalDate;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -84,6 +85,9 @@ public class App extends Application {
@Override
public void init() throws Exception {
LOG.info("Starting KeepTime.");

setLocaleToEnglish();

final DefaultExceptionHandler defaultExceptionHandler = new DefaultExceptionHandler();
defaultExceptionHandler.register();

Expand All @@ -102,6 +106,22 @@ public void init() throws Exception {
model.setSpringContext(springContext);
}

private void setLocaleToEnglish() {
final Locale systemDefaultLocale = Locale.getDefault();
final Locale wantedApplicationLocale = Locale.ENGLISH;

if (systemDefaultLocale.getLanguage().equals(wantedApplicationLocale.getLanguage())) {
LOG.debug("Application locale already is '{}'. Nothing to do.", wantedApplicationLocale);
return;
}

LOG.info("Setting application locale to '{}', was '{}'.", wantedApplicationLocale, systemDefaultLocale);
Locale.setDefault(wantedApplicationLocale);
Locale.setDefault(Locale.Category.DISPLAY, wantedApplicationLocale);
// keep system locale for format conversions (date, currency, numbers)
Locale.setDefault(Locale.Category.FORMAT, systemDefaultLocale);
}

@Override
public void start(final Stage primaryStage) {
LOG.info("Initialising the UI");
Expand All @@ -117,12 +137,13 @@ public void start(final Stage primaryStage) {
}
}

public static void showErrorDialogAndWait(String title, String header, String content, final Exception e, Window window) {
public static void showErrorDialogAndWait(String title, String header, String content, final Exception e,
Window window) {
final Alert alert = new Alert(AlertType.ERROR);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
if(window != null) {
if (window != null) {
alert.initOwner(window);
}
final StringWriter sw = new StringWriter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static boolean openFile(final String filePath) {
final File file = new File(filePath);
final Runtime rt = Runtime.getRuntime();

if (!file.exists() || file.isFile()) {
if (!file.exists() || !file.isFile()) {
LOG.warn("Filepath does not seem to exist or does not point to a file: '{}'.", filePath);
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/de/doubleslash/keeptime/common/Resources.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public enum RESOURCE {

SVG_ROTATE_ICON("/svgs/rotate-solid.svg"),

SVG_PLUS_SOLID("/svgs/plus-solid.svg"),

ICON_MAIN("/icons/icon.png"),

/** CSS **/
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/de/doubleslash/keeptime/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ public Project addNewProject(final Project project) {
return project;
}

public Work addWork(final Work work) {
LOG.info("Adding work '{}'", work);
final Work saved = model.getWorkRepository().save(work);
// show in report if it belongs to today
final LocalDate today = dateProvider.dateTimeNow().toLocalDate();
if (today.equals(saved.getStartTime().toLocalDate())) {
model.getPastWorkItems().add(saved);
}
return saved;
}

public void updateColorSettings(final Color hoverBackgroundColor,final Color hoverFontColor,final Color defaultBackgroundColor,final Color defaultFontColor,final Color taskBarColor) {
settings.setTaskBarColor(taskBarColor);
Expand Down
Loading
Loading