All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
📖 Table of Contents
- ➤ Changelog
- ➤ 0.21.0 - 23.04.2026
- ➤ 0.20.0 - 16.03.2026
- ➤ 0.19.0 - 20.01.2026
- ➤ 0.18.0 - 08.01.2026
- ➤ 0.17.0 - 16.12.2025
- ➤ 0.16.1 - 30.10.2025
- ➤ 0.16.0 - 24.09.2025
- ➤ 0.15.11 - 15.09.2025
- ➤ 0.15.10 - 01.04.2025
- ➤ 0.15.9 - 01.04.2025
- ➤ 0.15.8 - 26.03.2025
- ➤ 0.15.7 - 25.03.2025
- ➤ 0.15.6 - 24.03.2025
- ➤ 0.15.5 - 20.03.2025
- ➤ 0.15.4 - 20.03.2025
- ➤ 0.15.3 - 20.03.2025
- ➤ 0.15.1 - 19.03.2025
- ➤ 0.15.0 - 19.03.2025
- ➤ 0.14.18 - 18.03.2025
- ➤ 0.14.17 - 18.03.2025
- ➤ 0.14.16 - 18.03.2025
- ➤ 0.14.15 - 17.03.2025
- ➤ 0.14.12 - 13.03.2025
- ➤ 0.13.3 - 25.02.2025
- ➤ 0.13.2 - 22.02.2024
- ➤ 0.13.1 - 21.02.2024
- ➤ 0.13.0 - 21.02.2024
- ➤ 0.12.0 - 17.04.2023
- ➤ 0.11.4 - 21.12.2022
- ➤ 0.11.3 - 25.11.2022
- ➤ 0.11.2 - 18.11.2022
- ➤ 0.11.1 - 18.11.2022
- ➤ 0.11.0 - 16.11.2022
- ➤ 0.10.0 - 27.04.2021
- ➤ 0.9.0 - 15.12.2020
- ➤ 0.8.0 - 15.10.2020
- ➤ 0.7.0 - 09.09.2020
- ➤ 0.6.0 - N/A
- ➤ 0.5.0 - 22.5.2020
- ➤ 0.4.0 - 11.5.2020
- ➤ 0.3.1 - 16.04.2020
- ➤ 0.3.0 - 20.03.2020
- ➤ 0.2.0 - 05.03.2020
- 🔑 Personal Access Tokens: Regular users can now mint their own API tokens from Settings > API tokens, with per-token permission scopes, tenant-level kill switch, and full admin visibility (#1370, #1371)
- 🛡️ Critical QA Fixes: Closed an open-redirect after OAuth login, fixed a bogus
success: falsefromsubmitPeriod, restored AD user search, and made Home/Reports tolerant of malformed URL state (#1365) - 📊 Reports UX Overhaul: ViewColumnsPanel gains Reset/Save/Cancel, multi-project filter for custom queries, compact date headers in Summary, and a fresh Excel export that reads the live column state (#1372, #1373)
- 📱 Mobile Summary Visibility: Fixed invisible hours in the Timesheet Summary card layout on mobile (#1364)
- 🧱 List Column Sizing Rewrite: Dropped the localStorage persistence layer in favour of content-sampled initial widths with admin-set
minWidth/maxWidth/idealWidthas the single source of truth (#1375)
- Personal Access Tokens (#1370)
- New "API tokens" tab in User Settings for self-service token creation (name, expiry, permission picker)
- Server:
ApiTokentype gainstypeanduserId;RequestContextgainstokenSource;handleTokenAuthenticationpopulatesuserIdfor PATs so actions are attributable - New
PersonalAccessTokenResolverenforces a permission-subset rule (users cannot grant permissions they don't hold) - Tenant-level
security.personalAccessTokensEnabledkill switch in Subscription Settings - Admin API Tokens page shows a token type column and can revoke any user's PATs
- English and Norwegian i18n keys
- PAT actor fallbacks (#1371)
userIdis used as the actor when PAT-authenticated requests lock periods or invite external users- Report-link writes no longer fail on missing interactive
user.displayName
- ViewColumnsPanel: Reset / Save / Cancel (#1372)
- Snapshot / revert support at the top of the panel so users can experiment without committing
- Custom query report: Excel export + multi-project filter (#1372)
- Export button added, filter card runs full width, project picker uses the
InteractionTagmulti-select pattern - Server:
ReportsQuerygains aprojectIdsarray field for multi-project filtering
- Export button added, filter card runs full width, project picker uses the
- Autosize for list column widths (#1375)
- New
estimateColumnWidthhelper samples the first N rows of plain-text columns to pick a sensible initial width; columns usingonRender/renderAsfall back to their configuredidealWidth/defaultWidthrather than guessing - New
autoSizeColumns(defaulttrue) andautoSizeSampleSize(default50) props onIListProps
- New
- Excel export: single source of truth for columns (#1373)
- Removed the hardcoded
hiddenFromExportcolumn property; export now respects theViewColumnsPanelvisibility state, which is already persisted per list useExcelExportCommandreadscontext.state.columns(live user selection) instead ofcontext.props.columns(static defs)- Reports defaults cleaned up:
startDateTimeShort/endDateTimeShort,startEndDateTime, andperiodhidden by default; fullstartDateTime/endDateTimevisible by default
- Removed the hardcoded
- Excel export: stale column state fix (#1372)
- Export now reads column visibility from localStorage at export time instead of via
useBrowserStorage(which only snapshots at mount)
- Export now reads column visibility from localStorage at export time instead of via
- Summary report: compact layout (#1372)
- Date headers show
23-29.03instead of23 - 29 Mar; employee column widened to 190px
- Date headers show
- DataGrid column width ceiling (#1372)
- Column widths capped at 2000px to prevent runaway last-column sizing
- List column sizing: persistence removed (#1375)
useColumnWidthPersisthook deleted; the previous implementation wrote to localStorage with a key derived from column keys, which silently collided across lists that shared column-key sequencespersistColumnWidthsprop removed fromIListPropsand fromReportList- Extracted
MAX_COLUMN_WIDTH(2000),DEFAULT_MIN_WIDTH(50), and character/padding constants intoclient/components/List/hooks/columnSizing.ts
- Open redirect after OAuth login (#1365)
server/routes/auth.tsvalidatesredirectUrland rejects non-relative / protocol-relative paths, matching the guard already present on the session-injection route
submitPeriodreturningsuccess: falseon success (#1365)- Copy-paste bug in
TimesheetResolver.ts; the success path now returns{ success: true }
- Copy-paste bug in
- AD user search returning empty results (#1365)
graph_users.tsprojection was stripping all user fields; explicitly includes everyActiveDirectoryUserfield alongside the text score
- Malformed URL state crashing Home / Reports (#1365)
getUrlState,useHome, anduseCustomQueryFilterCriteriasnow silently ignore bad base64 / JSON instead of throwing during render
- Summary view hours invisible on mobile (#1364)
- Fluent UI v9 applies column widths as inline styles; on the mobile card layout this collapsed the value column to 0px.
.cell/.treeGridCellnow usewidth: 100% !importantinside themax-width: 600pxmedia query, while.selectionCellstaysautoso the checkbox isn't affected
- Fluent UI v9 applies column widths as inline styles; on the mobile card layout this collapsed the value column to 0px.
- Auth hardening and client stale-state (
f72ff5ef5)authCheckertreats an empty permissions array as unauthenticated- Added missing dependencies to
useCustomers,useProjects,EventList/useColumns, and Timesheet hotkeys so stale provider/context values no longer leak through useAppactivity detector effect now returns its cleanup so event listeners don't leak on remount- Disabled Apollo variable reporting in
setupGraphQLand tightened related types
- Shared layer decoupled from server (
f72ff5ef5)- Introduced
IHolidayObjectinterface inshared/types/; removed server imports fromshared/
- Introduced
- Webpack (
f72ff5ef5, #1372)- Production builds use
MiniCssExtractPluginto emit a stylesheet instead of inlining CSS BundleAnalyzerPluginwired up behind--analyze- Watch polling enabled so the Docker macOS volume mount picks up changes
- Production builds use
- Docker bootstrap hardening (
e2faefa11)scripts/docker.sh:ensure_env_filenow seeds from.env.sampleinstead of writing a minimal stub- New
check_required_envwarns on missing / placeholderSESSION_SIGNING_KEYandAPI_TOKEN_SECRET mongo-expressandredis-commandercredentials read from env vars (ME_BASICAUTH_USERNAME/PASSWORD,HTTP_USER/HTTP_PASSWORD) with sensible defaults- Pinned
redis-commanderimage by digest instead of:latest .env.sampledocuments the admin-tool credential vars
- Version bump tooling (this release)
.tasks/updateVersion.jsnow scaffolds.changelog/<version>.mdfrom a stub and prepends the[[load:...]]directive to.changelog/CHANGELOG.md, so future bumps don't need manual changelog plumbing
.gitignorecleanup (947e04130, #1375)- Removed stale temporary and documentation-related entries
- Added
did-*/so local git worktrees stay untracked
- Docker docs corrected (#1367)
- Fixed absolute-vs-relative script paths in
docker/DOCKER.md(/scripts/...->./scripts/...) - Corrected the MongoDB collection name from
timeentriestotime_entriesindocker/data/README.mdanddocker/DOCKER.md - Replaced the non-existent
npm run docker:setupreference with./scripts/docker.sh startindocker/sample-data/README.md
- Fixed absolute-vs-relative script paths in
- Personal Access Tokens design spec and implementation plan checked in under planning docs (#1370 follow-ups)
/didskill and did-cli design spec and implementation plan checked in for the upcoming Claude Code integration
npm run lintpassesnpm run build:serverpassesnpm testpasses (2565 tests, including newestimateColumnWidthunit tests)
- 📦 Dependency Upgrade Sweep: Upgraded core runtime, build, and UI dependencies across client and server
- 🧰 Lint Stack Modernized: Upgraded
@typescript-eslintparser/plugin to support TypeScript 5.9 - 🚀 Client Output Target Updated: Raised client TypeScript target from ES5 to ES2018 for modern browser environments
- 🐛 ISO Week/Year Bug Fix: Fixed long-standing inconsistency in
DateObject.toObjectfor ISO week/year calculations (#1027) - 📅 Cleaner Timesheet View: Empty weekend days (Sat/Sun) are now hidden in the timesheet overview
-
Tooling & TypeScript
- Upgraded
typescriptto5.9.x - Upgraded
@typescript-eslint/eslint-pluginto8.56.1 - Upgraded
@typescript-eslint/parserto8.56.1 - Kept
eslinton8.57.1(compatible with the upgraded TypeScript ESLint stack) - Added
skipLibCheck: trueto roottsconfig.jsonto handle type inconsistencies across upgraded third-party declarations - Fixed
export typefor type-only re-exports (FetchPolicy,IDatePeriod) forisolatedModulescompatibility
- Upgraded
-
Client Build Configuration
client/tsconfig.json:compilerOptions.targetchanged fromes5toes2018
-
Dependencies
- Upgraded multiple core dependencies, including Apollo Server, Fluent UI packages, GraphQL, TypeGraphQL, Webpack, Sass, and related typing packages
- Removed
node-fetch— replaced by nativefetch(requires Node ≥18, already enforced byenginesfield) - Moved
@types/mongodb,@types/react-windowfromdependenciestodevDependencies - Removed
@primer/css— no longer used after EntityLabel refactor
-
Docker Development Workflow
- Added
.tasks/runDockerWatch.js: smart wrapper that runsnpm cionly whenpackage.jsonorpackage-lock.jsonhas changed, with up to 3 retries, then falls through tonpm run watch - Dockerfile
CMDupdated to userunDockerWatch.jsinstead of invokingnpm run watchdirectly - Simplified
docker:rebuild:watchnpm script to usedocker compose up --build
- Added
-
Scripts & Project Structure
- Moved
.scripts/→scripts/and.deploy/→scripts/for cleaner top-level layout - Updated
.dockerignoreto reflect new script paths
- Moved
-
EntityLabel Component
- Replaced
@primer/cssmixin-based styles (labels-base,labels-large) with self-contained CSS inEntityLabel.module.scss, removing the external CSS framework dependency
- Replaced
-
Timesheet Overview
- Empty weekend days (Saturday/Sunday) are now hidden in the timesheet overview, reducing visual clutter
- Fixed ISO week/year bug in
DateObject.toObjectwhere week number and year could be inconsistent around year boundaries (#1027), with new test coverage
- Added changelog entry for version
0.20.0 - Added detailed
AGENTS.mdfiles forclient/,server/,shared/,docker/, andwebpack/contexts; refactored rootAGENTS.mdto reference them - Updated issue and pull request templates for clarity and consistency
- Updated README logo to use gradient SVG matching the landing page (#1355)
- Removed outdated holiday configuration document from the previous
docs/path - Moved
DOCKER.mdtodocker/DOCKER.md
npm run lintpasses with TypeScript 5.9-compatible lint toolingnpm run build:serverpassesnpm run package:clientpassesnpm testpasses (506 tests)
- 🎨 Major UI Framework Migration: Completed migration from Fluent UI v8 to v9, bringing modern design, better performance, and improved accessibility
- ♻️ List Component Rewrite: Completely rewrote List component using DataGrid and TreeGrid for better performance and maintainability
- 🎯 Icon System Overhaul: Migrated to Fluent UI v9 icon system with fallback handling and improved developer experience
-
New Components
- DataGrid-based List component with improved selection and grouping
- TreeGrid support for hierarchical list structures
- Skeleton loading states replacing legacy Shimmer components
- v9 Dialog component replacing Modal
- v9 Drawer component replacing Panel
-
Icon System
- ErrorCircle fallback icon for missing icons in catalog
- Development mode console warnings for missing icons
- Support for bundled filled/regular icon variants
-
Types & Enums
SelectionModeenum (string-based: 'none', 'single', 'multiple')CheckboxVisibilityenum ('hidden', 'onHover', 'always')- Enhanced
IListColumninterface with v9-compatible properties
-
Dependencies
@fluentui-contrib/react-tree-grid^0.3.2 for hierarchical lists
-
Theme System
- Removed legacy
ThemeProviderandPortalCompatProvider - Simplified to single
FluentProvider(v9 only) - Body background and text colors now applied via useEffect
- Removed
fonts.tsand legacy theme complexity - Dark theme updated with GitHub-inspired colors
- Removed legacy
-
List Component (Breaking Changes - See Migration Guide)
- Migrated from
ShimmeredDetailsListtoDataGridandTreeGrid - Removed
ListGroupHeaderandListHeadersubcomponents - Selection state management optimized (single-pass computation)
- Removed props:
onItemContextMenu,onColumnResize,dragDropEvents,listProps enableShimmernow uses Skeleton instead of Shimmer- Column resizing not implemented (
isResizableprop accepted but non-functional)
- Migrated from
-
Icon Handling
- Replaced
getFluentIconWithFallbackwith enhancedgetFluentIcon - Icons now use v9 bundled icon system
- Missing icons show ErrorCircle fallback instead of silent failure
- All icon imports updated to
@fluentui/react-icons
- Replaced
-
Component API Updates
Modal→Dialogwithopen/onOpenChangeinstead ofisOpen/onDismissPanel→Drawerwith v9-compatible propsCheckboxlabel prop now supports complex ReactNode contentContextualMenu→Menuwith v9 menu componentsformatfunction now usesstring-formatpackage (API-compatible)
-
Import Paths
DateRangeType,DayOfWeeknow from@fluentui/react-calendar-compatSelectionMode,CheckboxVisibilitynow fromcomponents/List/types- All icon components from
@fluentui/react-icons
-
Critical Issues
- Icon system now has proper fallback mechanism (no more null icons)
- Theme component cleanup prevents memory leaks on unmount
- Dialog
onDismissonly called once on close (not multiple times) - List selection state optimized to prevent unnecessary re-renders
-
Performance
- Removed redundant
itemMetaMap in List component - Combined three separate useMemo hooks into single-pass computation
- Filter panel signature-based deduplication prevents infinite loops
- Removed redundant
-
UI Fixes
- ProjectList component rendering fixed for v9
- Unmatched time entries rendering corrected
- Mobile breadcrumb authentication check relocated
- ScrollablePane replaced with CSS sticky positioning in LabelPicker
-
Migration Guide: Created comprehensive
_doc/MIGRATION_V8_TO_V9.md(250+ lines)- Documents all breaking changes with code examples
- Workarounds for removed features
- Testing checklist
- Known limitations
-
Code Review: Created
_doc/review/CODE_REVIEW_PR1328.md- Detailed analysis of critical, high, and medium priority issues
- Prioritized TODO list for fixes
-
Fix Summary: Created
_doc/review/FIXES_APPLIED.md- Complete documentation of all fixes applied
- Before/after comparisons
- Testing recommendations
-
Type Documentation: Enhanced inline documentation
SelectionModeenum with import warningsIListColumn.isResizabledocumented as non-functionalCheckboxVisibilityenum values explained
- Manual testing required for:
- List selection (single/multiple modes)
- Icon rendering with missing/undefined names
- Theme switching
- Filter panel interactions
- LabelPicker checkbox labels with SubText
- HotkeyModal open/close cycles
-
Code Quality
- Removed duplicate conditions in filter logic
- Optimized filter panel with useCallback and useRef
- Enhanced error handling with dev mode warnings
- Added ESLint disables with explanatory comments
-
Type Safety
- Updated component types to use v9 ButtonProps
- Enhanced IColumn interface for v9 compatibility
- Removed v8 type dependencies
-
Build System
- Package.json updated to Fluent UI v9 packages
- Removed legacy v8 dependencies
Known Limitations:
- Column resizing not implemented in new List component
- Drag and drop not supported in new List component
- Row context menus must be implemented in column render functions
- Complete holiday management system for accurate timebank calculations
- Full CRUD UI for configuring national and company-specific holidays
- Norway holiday preset with automatic Easter calculation
- Comprehensive validation, error handling, and timezone-safe date handling
- Holiday management UI in Admin > Subscription Settings (#1325)
- Full CRUD interface with DataGrid for managing holidays (add, edit, delete)
- Import from country presets (Norway with 13 holidays including movable Easter dates)
- Automatic Easter calculation using Anonymous Gregorian algorithm for movable holidays
- Holiday configuration affects timebank calculations by reducing expected work hours
- Validation for holiday dates (ISO format), names (1-100 chars), and hours (0-8 in 0.25 increments)
- Real-time warnings for duplicate dates, weekend holidays, and leap year issues (Feb 29)
- Support for recurring and non-recurring holidays
- Support for half-day holidays (e.g., New Year's Eve: 4 hours)
- Timezone-safe date handling with ISO date strings (YYYY-MM-DD)
HolidayValidationErrorclass for structured error reporting- Comprehensive validation functions:
validateHolidayDate(),validateHolidayName(),validateHoursOff() - Easter calculation functions:
calculateEasterSunday(),generateMovableHolidays() - Helper functions:
isWeekend(),findDuplicateHolidays(),getWorkingDaysInPeriod() - Performance optimizations with
useMemoinuseWorkWeekStatushook - Comprehensive unit test suite with 50+ test cases covering all scenarios
- Internationalization: Added 25 new holiday-related labels (en-GB, nb, nn)
- Documentation: Complete
HOLIDAY_CONFIGURATION.mdguide (312 lines)
useWorkWeekStatushook now accounts for holidays when calculating timebank- Enhanced
getHolidayHoursInPeriod()with error handling, validation, and logging - Improved
HolidaysFieldcomponent with proper TypeScript types (replaced allanytypes) - Updated subscription settings to include
holidaysconfiguration section - Timebank calculations now subtract holiday hours from expected work hours
- Error handling throughout with try-catch blocks and graceful fallbacks
- Fixed type safety issues in holiday configuration (eliminated all
anytypes) - Fixed timezone handling to prevent date shifts across timezones
- Fixed leap year handling for Feb 29 holidays (warns and skips in non-leap years)
- Fixed silent calculation failures with comprehensive error logging
- Fixed missing validation for negative hours, excessive hours, and invalid date formats
- Fixed performance issues with memoization of holiday calculations
- Added comprehensive
HOLIDAY_CONFIGURATION.mdwith architecture overview, configuration guide, API reference, and troubleshooting - Updated
CODE_REVIEW_PR1326.mdwith detailed implementation notes and resolution summary - Added JSDoc comments for all holiday utility functions
- Documented timezone handling strategy and edge cases
- Included best practices and known limitations sections
- Created
holidayUtils.test.tswith 50+ test cases (413 lines) - Test coverage: validation, timezone handling, Easter calculations, holiday hours calculations, edge cases
- All critical paths tested including cross-year periods, recurring holidays, and error scenarios
- Refactored holiday utilities into reusable validation and calculation functions
- Improved error handling with structured error classes
- Enhanced code quality with proper TypeScript interfaces
- Performance optimizations with React hooks memoization
- Separated timezone logic into dedicated helper functions
This release introduces a complete holiday management system that ensures accurate timebank calculations during holiday periods. Without holiday configuration, employees working during weeks with national holidays would incorrectly show negative timebank balances. The system supports both fixed holidays (recurring annually) and movable holidays (e.g., Easter-related), with automatic calculation for movable dates. The implementation includes comprehensive validation, error handling, and timezone-safe date operations.
Example: Week 52 2025 (Dec 22-28) with 3 Norwegian holidays (Dec 24-26, 24 hours total) now correctly reduces expected hours from 40 to 16, preventing incorrect negative timebank for employees who work only Mon-Tue (16 hours).
- Bulk edit capability for projects and customers
- Enhanced error handling and delta link management for Entra ID user synchronization
- Major dependency updates with security vulnerability fixes
- Improved environment configuration management
- Better Developer experience; removed localtunnel dependency in favor of Cloudflare Tunnel reverse proxy support
- Bulk edit capability for projects and customers (#1314)
- New
updateProjectsandupdateCustomersGraphQL mutations - Multi-selection support in ProjectList and CustomerList
- Enhanced error handling in user sync mutations with improved feedback
- Delta link expiration handling in MSGraphDeltaService
- Extended query timeout support for Entra ID user sync operations
- Progress indicators for user synchronization operations
did.instructions.mdagent instruction file for development workflow- Reverse proxy and Cloudflare Tunnel support for dynamic OAuth callback URLs
- New
getCallbackUrlutility function for constructing OAuth URLs based on incoming request - Debug logging for proxy requests in development mode
- Comprehensive documentation for reverse proxy setup in
REVERSE_PROXY_SUPPORT.md
- Bulk edit panels pre-populate shared field values and reuse common form controls
- Opening the bulk edit panel immediately snapshots the selected items for a stable editing experience
- Improved error handling and delta link management for Microsoft Graph API integration (#1321)
- MSGraphDeltaService now gracefully handles expired delta links with automatic fallback to full sync
- User sync mutations now return structured error information to the client
- Refactored dotenv configuration for streamlined environment management (#1315)
- Consolidated
.env.samplefiles - removed separate production sample in favor of unified configuration - Updated
.gitignoreto better manage environment files - Updated all project dependencies to latest stable versions with security patches
- Migrated from deprecated
@octokitpackages to current versions - Replaced deprecated
string-strip-htmltype definitions - Enhanced type safety in GitHub service with proper numeric conversions using
parseInt - Express app now trusts proxy headers (
X-Forwarded-Proto,X-Forwarded-Host) for proper URL construction behind reverse proxies - OAuth redirect URIs (
MICROSOFT_REDIRECT_URI,GOOGLE_REDIRECT_URI) are now optional - app dynamically constructs callbacks based on incoming request - Azure AD and Google OAuth strategies now support dynamic callback URL construction per request
- Webpack configuration handles missing
MICROSOFT_REDIRECT_URIgracefully with localhost fallback - Docker Compose override configuration updated to handle optional redirect URI environment variables
- Session storage enhanced to preserve original request protocol and host for OAuth flows
- Bulk project updates stringify the
extensionspayload to satisfy the GraphQL schema - Bulk project and customer mutations always include updated labels and no longer drop selection while editing
- Delta link expiration now properly triggers full sync fallback instead of failing
- User sync operations no longer fail silently on delta link errors
- Security vulnerabilities in dependencies resolved through major update
- Deprecated
@types/string-strip-htmldependency removed - Type safety issues in GitHub service numeric conversions
- Added
did.instructions.mdfor AI coding assistants - Improved documentation for user synchronization error handling
- Updated environment variable documentation with simplified
.env.sample
- Removed unused
defaultCheckedprop from NavigatePeriodsButtons component - Cleaned up package-lock.json to remove deprecated Octokit dependencies
- Version bump to 0.17.0
- Refactored numeric string conversions in GitHub service for better type safety
- Improved code quality with explicit
parseIntusage over implicit number coercion
This release focuses on bulk editing capabilities, enhanced synchronization reliability, dependency maintenance, and developer experience improvements. The addition of reverse proxy support enables seamless deployment behind Cloudflare Tunnels and other reverse proxies, with OAuth callbacks automatically adapting to the incoming domain without requiring multiple environment configurations.
- Dedicated permission for locking/unlocking weeks
- New "Partner" field on Customer Projects
- Entra ID user search backed by MongoDB
graph_userscache and Microsoft Graph delta sync
- New
LOCK_UNLOCK_WEEKSpermission (a7b8c9d0) protecting thelockPeriodmutation. - Added "Partner" field to Customer Project to support subcontractor billing workflows (#1301).
- Introduced Entra ID user search with persisted
graph_userscollection and delta retrieval to keep cached profiles fresh (#1306). - Enhanced User Management form with autocomplete search for Entra ID users including automatic loading, performance optimizations, and visual distinction for already-added users (#1306).
- Role permissions for authenticated users are now resolved dynamically per request (no logout required after role updates).
- Webpack Git metadata integration now auto-disables when
gitor.gitare unavailable (falling back to environment variables orunknown), preventing dev container build failures. - Express fallback error response changed from 401 to 404 to reduce noisy Unauthorized logs for missing/static assets.
- JSON 404 responses returned for API/GraphQL style requests and clients that explicitly accept JSON.
- Applied employment date filtering to Week Status user queries so inactive users no longer appear in reporting (#1290).
- Improved User Management UX by removing manual "Load users from Entra ID" button and implementing automatic loading on panel open (#1306).
- Enhanced autocomplete performance with Set-based O(1) lookups and React memoization for large user datasets (#1306).
- Added persistent form state management ensuring search checkboxes maintain values across all user interactions (#1306).
- Hardened manager enrichment service with production-ready error handling, distributed worker coordination, and heartbeat monitoring (#1306).
- Development watch task crash due to incorrect
concurrentlypromise handling (removed.resultusage; added robust promise resolution). - Silent failure to start webpack watcher inside Docker because
.tasksdirectory was ignored; adjusted.dockerignoreto include onlywatch.js. - Potential build crash when
gitbinary absent (now gracefully skipped). - Reduced log noise by suppressing morgan output for 404 static asset requests (hashed bundles / images between rebuilds).
- Fixed
UserVacationtooltip ref error by forwarding refs through theMenuItemcomponent to the underlying Fluent UI primitive (#1304). - Resolved checkbox state persistence issues in User Management form ensuring
includeUsersWithoutGivenNameandshowAlreadyAddedUsersmaintain values during form operations (#1306). - Fixed autocomplete disabled item styling and selection behavior for already-added users (#1306).
- Enhanced manager enrichment service with exponential backoff retry logic, rate limiting protection, and comprehensive error categorization (#1306).
- Added helper npm scripts
docker:watchanddocker:rebuild:watchfor a canonical rebuild/start workflow without wiping MongoDB volumes. - Added diagnostic logging to watch script (explicit process start lines, colored prefixes, failure summaries).
- Improved resilience of dev build by auto-detecting absence of Git and avoiding unnecessary image bloat.
- Version bump to 0.16.1
This release focuses on permission granularity, session freshness and developer experience improvements.
- Deterministic Docker startup (Redis healthcheck + sequencing) eliminates race conditions
- Reproducible Docker builds with lockfile-only install, retry/backoff, and embedded git revision & branch
- Seed data insight & safety: size logging,
--statusnon-destructive mode, placeholder secret detection - Dynamic multi-arch capable build (env-driven platform selection) & normalized image naming
- Security & hygiene: tighter
.dockerignore, secret warnings, reduced context footprint - Expanded developer guidance: new
AGENTS.md, consolidated Docker docs, accessibility & i18n/testing standards - Auth routing refined so static assets & API routes are public while protected routes remain gated
- Redis healthcheck and deterministic service startup in Docker Compose
- File size logging for MongoDB seed data import
- Placeholder secret detection, seed summary, and
--statusflag indocker-quickstart.sh - Common reset recipes and security notes in DOCKER.md
- Git build metadata embedding (revision & branch) in Docker/Webpack build
- Dynamic Docker build platform selection (env-driven)
- Normalized Docker image naming for consistent tagging
- Central
AGENTS.mddeveloper reference (architecture & workflows) - Accessibility requirements and expanded i18n/component/testing standards documentation
- Enforced lockfile integrity in Dockerfile (removed fallback to
npm install) - Updated
.dockerignoreto exclude secrets and seed data - DOCKER.md condensed and clarified for onboarding and troubleshooting
- Resilient npm install with retry/backoff & caching improvements in Dockerfile
- Authentication routing updated to treat static assets & API routes as public
- Consistent lowercase project naming (
did) - Adopted modern
docker composecommand syntax - Increased Docker build test timeout to 300s
- Redis cache port configurability added
- Standardized MongoDB database name to
mainacross code and docs
- Removed unused code, comments, and documentation from Docker scripts and configs
- Startup race conditions mitigated via healthcheck sequencing
- Prevented omission of Webpack assets from Docker build context
- Expanded Docker quickstart, troubleshooting, and security guidance
- Added central architecture & workflow reference (AGENTS.md)
- Clarified seed import/reset process & non-destructive status mode
- Added accessibility & development standards (i18n, data management, component structure, testing)
- General QA and refactor of Docker-related files
- Version bump to 0.16.0
This release focuses on dockerization, developer experience, and security hygiene for local development.
- Account enabled checkbox added to the User form (enabled even when syncing from AAD)
- Subscription settings now allow optionally syncing "accountEnabled" from AAD
- Lazy loading for Active Directory users in bulk import panel with "Load Users" button
- Search functionality for Active Directory (Entra ID) users with server-side filtering
- Progress indicators for Entra ID user loading operations
- Add New User panel now supports lazy loading of Entra ID users and local filtering in the picker
- Internationalization: added new labels for Entra ID user loading and user sync menu (en-GB, nb, nn)
- Default bulk user sync no longer includes "accountEnabled" unless explicitly selected
- Performance: Entra ID users (≈19k) no longer fetched on initial page load, improving Admin > Users load time from ~5s to ~500ms
- User synchronization menu now shows context-aware text (all users vs. selected users)
- Bulk import panel now requires explicit "Load Users from Entra ID" action instead of auto-loading
- User sync operations now load Entra ID users on-demand with progress messaging
- Add New User panel no longer performs server-side search after initial load; uses client-side filtering
- Sync action is disabled while Entra ID users are loading, with contextual progress text
- Eliminated performance bottleneck caused by fetching all Entra ID users on every Admin > Users page load
- Fixed AVA test runner configuration (ESM loader cycle) that caused all tests to fail
- Minor adjustment to Google Calendar service
- Added
CLAUDE.mdwith project guidance and development instructions - Updated Copilot and contributor instructions
- Enhanced and refactored automatic chores workflow (creation, PR behavior)
- Disabled automatic chores workflow (temporarily) for stability
- Updated contributors list
- Version bump to 0.15.11
This release focuses on significant scalability improvements for large Entra ID tenants and lays groundwork for more responsive administrative workflows.
- Minor fix for labels in Reports #1281
- Added support for including project labels in reports #1281
- Improved administration of subscription setting
security.domainRestrictionExternal.
- Fixed an issue with the customer projects query on the customer page.
- Reload button not available when a period is confirmed
- Added support for enabling maintenance mode
- Added "Reload" button to timesheet to fetch fresh data from Microsoft Graph without using cache
- Refactored server routes with improved error handling during page rendering
- Added Terms of Service and Privacy Statement pages with initial content
- Added health check endpoint
/health_checkto the backend
- Now running on Node 22 LTS
- Refactored user context handling into session context, improving initialization flow and type safety
- Proper link styling for links in the
Markdowncomponent
- Fixed critical bug in
SummaryViewforTimesheetpage that caused the component when there were unmatched events
- Improvements to the
EventListrendering in theProjectPopovercomponent in theSummaryView - Users with no hours in selected periods are now filtered out in the
SummaryView
- Removed unneccessary margin from the
EventListcomponent
- Enhanced
ProjectPopoverwith support for extra content (f.ex.EventList) and improved component structure for better project information display
- Updated UserPicker component to use TagGroup and InteractionTag components for better accessibility and user experience
- Enhanced form validation with connected fields support in BaseControlOptions and useFormControl
- Modified the CLEAR_VALIDATION_MESSAGES action to accept an optional string array of field names for selective validation clearing
- Fixed path reference for roleDefinitions in useRoleDefinitions.ts to properly access nested properties
- Added maxSuggestions parameter to SearchCustomer and ProjectPicker components for better performance
- Removed outdated removeUserDbClick message from i18n files (en-GB, nb, nn)
- Enhanced roles and permissions management UI
- Increased time entries loading capabilities + support for custom filters #1220
- Fixed an issue with project roles when manually matching in the UI
- Added support for deleting a customer #1165
- Fixed hourly rate calculation in project time entries by ensuring proper handling of undefined/null values
- Improved field default values for list input controls
- Added empty message for project time entries when autoload is disabled
- Fixed hourly rate display in
UserColumnby properly rounding hourly rates
- Fixed layout issue in Project Popover in Timesheet #1196
- Fixed issues with importing users from Entra ID #1230
- Improved readability on customer information page #1214
- Improved readability on project information page #1219
- Add support for setting default tab on Project page #1236
- Feature to select color preset for Outlook categories #1213
- Basic functionality for Budget Tracking #1217
- You know know add a security group in subscription settings, users in this group will be automatically enrolled in did #1182
- Customer and Project key max length is now configurable in subscription settings #1231
- Initial support for enhancing the resource management capabilities within the Projects module of our time entry system. #1237
- Showing week hours summary based on user work week #1138
- Manager included in user sync #1244
- Support for simple project hierarchy #1245
- Support for locking weeks from the admin UI #1249
- Enhancements to the Project Role Management #1245
- Add Parent Project to reports and Excel export #1253
- Fix for #1112
- Deactivated projects can no longer be selectable when resolving manually #1171
- Fixed Icon field will now be cleared when a new project has been created #1188
- Fixed Missing key prop on DetailsRowFields component #1147
- Fix for action bar glitching in Timesheet #1132
- Improved general look and feel - now using the new Fluent UI 9
- Company brand support #1170
- Enriched Subscription Teams settings with fields for Teams reminder messages #1185
- Added WeekStatus GraphQL API Endpoint for User Week Confirmation Status #1181
- Added support for uploading formatted reports and displaying them to end-users #1096
- Missing submissions is not showing hidden users #1089
- Vacation days reset per year by changing the user configuration format #1086
- Visualize if a day is a public holiday #1064
- Fixed an issue with Timesheet navigation that makes it sometimes skip a year #1028
- Fixed an issue with submit commands when there's no submit actions available #1070
- Improved Project and Customer pages #1069
- Visual upgrade for lists #1076
- Adjustments to calculation/estimation of vacation #1080
- Events without subject/title is now visible to the end user and displayed as an error that needs to be resolved before submitting #1082
- Fixed issue with user reports #1077
- Fixed issue with rounding of events #1065
- Fixed issues with retrieving customers affecting Project creation etc #1062
- Project code as filter to Reports #978
- Added permission scope LIST_USERS #968
- Support end early/start late: round appointments to nearest half hours #1056
- Autofocus and up/down arrows navigation support for Autocomplete component #1058
- Implemented month view #70
- Project reports includes week number #975
- Reports performance issues #984
- Reports infinite loops #994
- Unconfirmed hours included in summary view #1031
- Added total row to summary report #932
- Fix for feedback locked #1042
- Summary report shows current week #980
- Moved delete button out of edit form for roles #935
- Deleting API-keys and labels now requires confirmation #953
- Support for split week, split year scenarios #753
- Last year option added to reports #775
- Support for deleting role #692
- Improved Timesheet statusbar: Now showing on all tabs, and showing either shimmer or progress indicator, not both. #831
- Nynorsk (nn-no) language support #864 (thanks to @paalolav ❤️)
- Support for initial signin with email #884
- Showing more details in the summary view on hover #886
- Summary view moved to Reports
- Differentiating 0-hour weeks from unconfirmed weeks in Summary view #781
- Synchronize user photo from Azure AD #899
- Breadcrumb for mobile devices
- New user setting: Start page
- New user setting: Sticky Navigation
- Support for submitting feedback
- Issue where filtering on a report would crash the page #938
- Issue where moving an event from a confirmed week to an unconfirmed week would cause an error #766
- Issue where confirmed hours would be skewed forward one hour #760
- Issue with navigating between tabs in Projects #749
- Minor visual bug in unmatched hours #773
- Issue with rogue customer matches in large event bodies #782
- Issue where sunday hours would not be displayed in the UI after confirming a week #785
- Issue with time entry queries in Reports #790
- Issue with navigating to a customer from e.g. Timesheet #791
- Issue with navigating directly to a page when not logged in #889
- Consistent ignore/match buttons across devices in Timesheet #894
- Consolidated server and client date utils #771
- Summary view now using datepicker instead of slider #777
- Visual improvements on the admin sections
- Changes to forecast/confirm actions #605
- Improvements to allocation view in Timesheet #644
- Forecast notifications #613 (can be turned off in subscription settings #639)
- Improved forecast/confirm actions #605
- Automatic Azure Active Directory sync #661
- Support for API tokens with scoped permissions #635
- Export hours from user menu #589
- Improved project tooltip/panel #678
- When debugging, local cache is automatically cleared on first run #715
- Improved project selector #671
- Support for editing customers #672
- Resizable columns in Reports #722
- Added project tooltip to Summary view in Timesheet #677
- Side panels are now light dismissable #734
- Project suggestions in timesheet matching now also works for event body #705
- Fixed issue where ignored events were not persisted #730
- Minor UI adjustments in Timesheet
- Fixes in matching engine #603
- Issue with appointments occuring around midnight Sunday #703
- Lag in customer/project search #686
- Reports: Current month and year in Reports included entries after today's date #738
- Reports: Filters would persist when switching reports #733
- Reports: Current month report bug #710
- User settings: display language dropdown value would not change after switching language #740
- Customers: Searching for newly created customers would return zero results #739
- Fix for 'go to current week'-shortcut #707
- Decreased Project and Customer keys min length to 2 #681
- Increased Project and Customer keys max length to 12 #719
- Dependency on moment.js removed, now using day.js instead
- did now supports forecasting #355
- Better mobile navigation with descriptive labels #539, #588
- We now have custom error pages #502
- Better error messages #579
- Showing aggregated hours per group in Reports #541
- Support for setting Projects to inactive in UI #524
- Better log in/log out experience #485
- Fixed an issue with split weeks where the returned events and total hours were wrong #578
- Missing week summary on Admin page #569
- Could not open week picker in Timesheet under certain conditions #558
- did now properly matches ÆØÅ in customer and project keys #550
- Rebrand to just "did" #412
- Improved reports landing page #505
- Added customers as a separate column in the Timesheet overview #496
- Show project ID (full key) in ProjectColumnTooltip #495
- Enabling GraphQL to be called externally using authorization tokens #478
- Show labels in the Summary view #461
- Possibility of tagging projects with labels in UI #333
- Deep linking for Projects #435
- Fixed soft match functionality (matching without (), [], {}) #489
- Customer entries with leading/trailing spaces are un-matchable #426
Need details.
- Added toggle for showing/hiding inactive projects andcustomers #285
- Redirect user to timesheet after logging in #303
- Adjustments to Reports #269
- Reports: Changed name of export button to 'Export current view' #269
- Hotkeys for Timesheet #337
- Summary view can be grouped by customer #242
- Support for Norwegian #306
- Fix for scrollbar glitching #302
- Support for split weeks #232
- Added user column to project overview #224
- Consolidating confirm buttons #270
- Confirm hours disabled when there's unmatched events #268
- Including project code in tooltip #243
- Presenting active/inactive status for customers and projects in views #168
- Changed chart library from
highchartstorechartsdue to licenses #273 - Support for adding DID365 as an app in Microsoft Teams #170
- Sorted customer options alphabetically by name in summary view(s) #260
- Support for adding a project as a category in the users mailbox #202
- Icon picker in project and customer forms #213
- Support for using did in Teams tabs. No SSO support for now #170
- Using
get-valuemodule to getproject.inactiveandcustomer.inactivefrom event #212 - Using
.isoWeek()instead of.week()to calculate week from startTime intimesheetresolver #225