No description
- Swift 58.8%
- HTML 31.4%
- JavaScript 9.6%
- Shell 0.2%
| .claude | ||
| AppIcon.icon | ||
| design | ||
| docs | ||
| plans | ||
| Scripts | ||
| Sources | ||
| .gitignore | ||
| CLAUDE.md | ||
| DESIGN.md | ||
| Info.plist | ||
| project.yml | ||
| README.md | ||
| renovate.json | ||
| TODO.md | ||
TEMPO-UI
A native SwiftUI macOS app (macOS 26) for viewing and logging your Tempo time on a day or week calendar.
Features
- Native macOS window — a sidebar with this week's days (Mon–Sat), each with its hours bar against the requirement and the overtime balance, and a timeline of the selected day or the whole week (the Day/Week switch, ⌘1 / ⌘2; the week view hides the sidebar). Worklogs are coloured blocks by issue, calendar events dashed outlines. The toolbar holds the week's hours with Submit Timesheet, and in the week view the overtime balance. Follows the system appearance (light or dark) and accent colour.
- Log time — click an empty slot (15-min default) or drag a span on the timeline, or use the
Log time button. The Work item field searches Jira live (by key or summary); pick a
result or type a key. Smart time entry:
930→09:30,1430→14:30; Start/End give a computed Duration. Worklog blocks can't overlap. Suggestions come from your calendar, recent worklogs and Jira issues assigned to you. Changes show an Undo toast, and Edit ▸ Undo (⌘Z) works too. - Edit / delete — click a worklog block to change its date/time/description, move it to another ticket, or delete it; drag a block to move it, or its edges to resize it. Hover a block for Duplicate and Delete.
- Overtime — the sidebar card (a toolbar popover in the week view) shows the balance, this month, this year and the carry-over, and one bar per month, computed from a configurable start date (default Jan 1) → yesterday, plus an optional carry-over balance. Right-click a day to mark it as an overtime day: it deliberately stays empty and its required hours draw down the balance.
- Personio absences — pick your Personio calendar in Settings and all-day absence events (keyword match, e.g. "Urlaub") are detected in the visible week and auto-booked on a configured vacation issue (or notify-only, via a toggle). A bell in the toolbar collects notifications (bookings, collisions with existing worklogs); the review dialog — reachable from notices, the Vacation/Overtime badges, or right-click — lists every detected day and lets you flip each between vacation worklog and overtime day at any time. Deleting a vacation worklog by hand counts as undo: the day is detected fresh again.
- Google Calendar — connect in Settings to see accepted meetings as striped blocks (with a calendar icon); click one to book a worklog prefilled from the event (Jira key detected from the event text). Hover an event and click the checkmark to book it in one click when exactly one Jira key is detected — otherwise the prefilled Log Time sheet opens. Already-logged events drop off.
- Settings window (⌘,) with General (Tempo & Jira, overtime, updates) and Calendars (Google Calendar, Personio, booking); each field saves when you press Return or leave it, and Personio and booking changes apply when you close Settings. Auto-refresh every 60s, paused while a sheet is open.
See docs/architecture.md for how it works.
Requirements
- macOS 26+
- Xcode 26+
xcodegen(brew install xcodegen) — the.xcodeprojis generated fromproject.yml, not committed.
Build & run
xcodegen generate # generate TempoUI.xcodeproj from project.yml
open TempoUI.xcodeproj # build & run in Xcode
# …or from the CLI:
xcodebuild -project TempoUI.xcodeproj -scheme TempoUI -configuration Debug build
The Swift Package dependency (GoogleSignIn) resolves automatically on first build. A Debug build
launched with -demo (add -dark for the dark appearance) shows a sample week without accounts.
Setup
Credentials are entered in the in-app Settings window (⌘, or the ⚙︎ button; it opens
automatically on first launch). Full step-by-step instructions are in docs/setup.md:
| For | You provide | Where it's stored |
|---|---|---|
| Tempo (required) | API token + Atlassian Account ID | token in Keychain, account id in UserDefaults |
| Jira (search + log) | site URL + email + Atlassian API token | token in Keychain, rest in UserDefaults |
| Google Calendar (optional) | an OAuth iOS client id (in Info.plist) |
tokens managed by the GoogleSignIn SDK |
Project layout
Sources/
TempoUIApp.swift App entry point: main window, Settings window, menu commands
Models/ Decodable DTOs (Worklog, ScheduleDay, CalendarEvent, MonthOvertime,
AbsenceNotice)
Services/ TempoClient, JiraClient, CalendarClient, GoogleAuth, KeychainStore
ViewModels/ DashboardViewModel, LogHoursViewModel
Views/ DashboardView (window, toolbar, week headers), SidebarView, DaySummaryViews,
DayTimelineView, OvertimeCard, LogHoursView, TimeField,
SubmitTimesheetView, AbsenceReviewView, NotificationsPopover,
SettingsView, JiraIssueSearchField
Support/ Theme (palette, motion), DateFormatting, JiraKeyMatcher, JiraHTML,
TimelineMode, TimelineZoom, DemoData, PersonioAbsenceDetector,
AbsenceLedger
Info.plist App icon name, Google URL scheme, GIDClientID
AppIcon.icon Icon Composer app icon
project.yml XcodeGen spec
docs/ architecture.md, setup.md