Sitelet https://github.com/MaxLikesCode/factorial-desktop
Skip to content

About

Floating widget and tray icon for tracking time in Factorial HR (Electron, macOS + Windows)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Factorial Desktop

The widget on the desktop: clocked in since 8:43:11, target met with +0:43, Pause and Clock out below

A small floating widget and a tray icon for tracking time in Factorial HR. Clock in, take a break, resume, clock out — without opening the browser.

The card sits on top of whatever you are working on and shows the day at a glance: how long you have worked, how much is left, and where the breaks were. Click it to open the full card, click again to collapse it.

Download

Grab the latest build from the releases page.

Platform File Notes
Windows Factorial-Desktop-Setup-<version>.exe Installs for your user only — no admin rights needed. Adds a Start-menu entry and can start with Windows. This is the one to pick.
Windows Factorial-Desktop.exe Runs from anywhere without installing. Handy for a USB stick or a locked-down machine.
macOS Factorial-Desktop-<version>-arm64.dmg Apple Silicon.

The first launch needs one extra step:

  • Windows: the build is not signed, so SmartScreen shows a blue box. Click More info → Run anyway.
  • macOS: nothing. The build is signed and notarized.

Using it

Signing in. The first launch opens Factorial's own login page in a window — the app never sees your password, and two-factor works exactly as it does in the browser. The session is kept, so the next launch goes straight to the widget.

The tray icon is where the app lives. It has no taskbar button and no dock icon on purpose: closing the widget only hides it. The icon's colour is the state at a glance — grey clocked out, green clocked in, amber on a break — and hovering shows the running time without opening anything.

Windows tip: new tray icons are hidden behind the ^ chevron by default. Drag it onto the taskbar once and it stays there.

The tray menu is the way to everything: clock in and out, pick a break type, show or hide the widget, and Settings for start-with-system, always-on-top, which way the card opens, light or dark, the language, and checking for updates.

Updates. The installed build checks for a new version half a minute after launch and every six hours after that, and always asks before downloading anything. If a shift is running it will not restart — the update is applied the next time you quit. The portable build cannot replace itself, so it points at the download page instead.

One thing worth knowing: this writes to your real timesheet. The app never guesses a time — when it loses contact with Factorial it shows the last known state and says so, rather than inventing something that looks plausible.

Language. The app follows your system language and falls back to English for anything it does not speak. Seven are included: English, Deutsch, Español, Français, Italiano, Português and Nederlands. To pin one, use the tray menu → Settings → Language.

Development

Node 22 or newer.

npm install
npm run dev
Command Purpose
npm run dev Dev mode with hot reload (electron-vite)
npm test Unit tests (Vitest, no Electron runtime needed)
npm run test:watch The same tests, watching
npm run typecheck TypeScript across main, preload, shared and renderer
npm run build Typecheck, then build to out/
npm run package:mac macOS: DMG + ZIP, arm64
npm run package:win Windows: NSIS installer + portable exe, x64

Both package: scripts run npm run build first, so a type error stops them before electron-builder starts. Artefacts land in release/, which is ignored.

Adding a language. Copy src/shared/locales/en.ts, translate the values, and add the code to LOCALES in src/shared/i18n.ts. TypeScript then names any key you missed, and the test suite checks that the placeholders ({time}, {version}) match English — a translated placeholder is the mistake that silently prints braces at a user.

Architecture in one paragraph. The main process owns the truth: it talks to Factorial's GraphQL API, keeps one attendance store, and pushes snapshots to the renderer over a ten-function contextBridge. The renderer draws and never decides — it has no Node, no require, and no way to reach the network. The pieces that can be tested without Electron are deliberately kept free of it and are, which is why the suite runs anywhere.

Tests. 517 of them, no Electron runtime required. They cover the time reconstruction, the store's optimistic updates and rollbacks, the IPC codec, the widget's five states, and the platform-dependent decisions — the last of those take their inputs as arguments precisely so that, say, the Windows autostart path can be checked from a Mac.

CI. .github/workflows/build.yml runs tests and typecheck on every push and pull request. Tagging v* builds both platforms and attaches the files to a GitHub release; macOS runners are billed at ten times the Linux rate, so the builds do not run on every push.

Releasing. One command produces the version commit and its tag, and pushing the tag is what starts a release build:

npm version patch          # or minor / major
git push origin main --follow-tags

Pushing to main on its own is not a release; only a v* tag is. The full procedure, how to pick the number, and the handful of things that have gone wrong before are in docs/RELEASING.md.

Documentation

  • docs/DESIGN.md — architecture and the full API reference, verified against the live API. Where anything disagrees, this wins.
  • docs/api-discovery.md — how the Factorial API was mapped out, and how to find a query nobody has needed yet.
  • docs/RELEASING.md — how to cut a release, when not to, and why signing and notarization are not optional on macOS.

About

Floating widget and tray icon for tracking time in Factorial HR (Electron, macOS + Windows)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages