Multi-stop ticktack, TOOLBAR_PINNED event, and plugin entry filtering#5844
Open
ralf1070 wants to merge 3 commits into
Open
Multi-stop ticktack, TOOLBAR_PINNED event, and plugin entry filtering#5844ralf1070 wants to merge 3 commits into
ralf1070 wants to merge 3 commits into
Conversation
dc4f17a to
d6df0b6
Compare
Render up to hard_limit stop buttons in the ticktack navbar. JS uses show/hide on pre-rendered slots instead of replacing a single button. Add ThemeEvent::TOOLBAR_PINNED slot before the ticktack for plugin buttons (e.g. attendance). Add TicktackExcludeEvent allowing plugins to exclude specific entries from the ticktack (both server-side Twig and client-side JS via data-exclude attribute on .ticktac).
Renders hard_limit - excludes.length slots instead of hard_limit, so plugin-managed entries (e.g. Attendance) don't consume visible ticktack slots. Start button hides when all visible slots are filled.
d6df0b6 to
c065ca3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here is the public part of the project that led me to the off by one error yesterday.
It's the common part of a refactoring of what I considered to be ugly JS code, which was necessary to solve the task I was given: to display a stop button for every job running in parallel and to keep a dedicated start/stop button for a specific activity always available.
I hope you can use it - I'd be happy if you could. If you find the idea interesting but would implement it differently, let me know. I still have a few hours in my time budget for it. And if it's not suitable for mainline, that's okay too - it solves the task I was given and I can maintain it outside of mainline.
I know - parallel jobs aren't your favorite topic. But my colleagues are fans of them. Life is hard...
Summary
hard_limitstop buttons instead of only the first active entryThemeEvent::TOOLBAR_PINNEDslot for plugins to place buttons before ticktackTicktackExcludeEventallows plugins to filter entries out of ticktackMotivation
When
timesheet.active_entries.hard_limitis set to more than 1, users can have multiple running timesheets simultaneously. However, ticktack in the navbar only shows the first active entry.This change renders all
hard_limitslots in the Twig template upfront. Active entries get real data, unused slots are hidden withdisplay:none. The JS (KimaiActiveRecords._setEntries()) only toggles visibility and updates content via the existing_replaceInNode()mechanism.TOOLBAR_PINNED event
For the job given I need to place a persistent action button in the navbar - in this case, a one-click attendance tracker that starts/stops a specific timesheet independently from the regular ticktack workflow.
The existing
ThemeEvent::TOOLBARrenders after the ticktack and recent-activities. To position a button before the ticktack, plugins had to resort to JS-based DOM reordering.TOOLBAR_PINNEDprovides a clean insertion point right before ticktack. Typical use case: a plugin manages a "special" timesheet (like attendance tracking) with its own start/stop button and wants it visually grouped with - but separate from - the regular ticktack buttons.TicktackExcludeEvent
When a plugin manages a specific timesheet via its own button (rendered through
TOOLBAR_PINNED), that entry would also appear as a regular stop button in ticktack - resulting in duplicate controls for the same entry.TicktackExcludeEventlets plugins declare which entries they manage themselves. Excluded entries are filtered out of ticktack both server-side (Twig initial render) and client-side (JS updates viadata-excludeattribute). The total entry count including excluded entries is still used for thehard_limitcheck, so the start button correctly reflects the system's capacity.Example: a plugin subscribes to the event and excludes entries matching a specific project + activity:
Each rule is an associative array where keys map to entry relations (
project,activity) and values are entity IDs. An entry is excluded when all keys in a rule match. Multiple rules are OR-combined.Changes
src/Event/ThemeEvent.phpTOOLBAR_PINNEDconstantsrc/Event/TicktackExcludeEvent.phptemplates/base.html.twigTOOLBAR_PINNEDbefore ticktack includesrc/Twig/Runtime/TimesheetExtension.phpSystemConfiguration+EventDispatcher, addactiveEntriesHardLimit(),ticktackEntries(),ticktackExcludes()src/Twig/RuntimeExtensions.phptimesheet_hard_limit,ticktack_entries,ticktack_excludesTwig functionstemplates/partials/ticktack.html.twighard_limitslots, use filtered entries for display, renderdata-excludefor JSassets/js/plugins/KimaiActiveRecords.js_setEntries()readsdata-exclude, filters display entries, uses total count for hard_limittests/Twig/Runtime/TimesheetExtensionTest.phpBehavior
hard_limit=1(default): Identical to current ticktack - one stop or one start buttonhard_limit>1: Up to N stop buttons, each with project name tooltip. Start button hidden when limit reached. On mobile, a colored dot (project color) distinguishes the buttons.data-title="true"on slot 0)son first stop button,non start button (only when no entries active)Types of changes
Checklist
composer code-check)