Commit Graph
4 Commits
Author SHA1 Message Date
thandClaude Opus 4.6 923de0cdd6 hotkeys, gitea ticket-from-card, collab unread, runner auto-retry
board hotkeys (public/js/app.js):
* "c" toggles the calendar from the board (no modifier, body focus,
  no full-screen overlay in front).
* "t" opens a tag quick-pick popover that lists every unique tag from
  state.cards. Filter input + arrow-key/enter pick + ESC/click-outside
  close. Picking sets state.activeTags = [tag] and re-renders the
  board + tag bar. Toggle: a second "t" press closes the picker.
* "1"-"9" picks the Nth user bucket in the bar. The fixed filters
  (all/current/favorites/journal/none) are skipped. Super-buckets
  count as one slot and activate via the new activateBucket() helper
  in buckets.js — that bypasses the click handler so the dropdown
  popover does NOT open; the currently shown member (parent or
  active child) is selected directly.
* ESC chain in the existing handler now also closes #calendar (was
  missing — calendar.js only handles ESC for the day-popup, not the
  whole overlay).

buckets (public/js/modules/buckets.js):
* New exported activateBucket(idOrSpecial) helper: setActiveBucket
  + clear activeGroup + renderBar + window._renderBoard. Used by
  the number-key hotkey to select super-buckets without triggering
  their dropdown.

board split panel (public/js/modules/board.js):
* closeBoardPreview() now removes the .active class from the
  toolbar's #board-split-toggle. The previous code removed
  .text-t-accent which was a no-op since toggleBoardSplit() uses
  .active — the X button on the panel closed the split but left
  the toolbar showing the toggle as still on.

email plugin (public/plugins/email/email.js):
* ESC closes the overlay reliably: the previous handler was on
  #email-overlay, which only fires when focus is *inside* the
  overlay (rare after open). Moved to a document-level keydown.
* Bare "m" toggles the mail overlay open/closed. Suppressed when
  Ctrl/Meta/Alt is held, focus is in an input/textarea/contenteditable,
  or any other full-screen overlay is in front.

collab-buckets (public/plugins/collab-buckets/backend.php):
* When a card change is applied in the pull phase from a foreign
  author (insert / update / tombstone), bump
  collab_buckets.updated_at to NOW for that bucket. has_unread is
  computed as updated_at > last_seen_at and was previously never
  triggered for incoming cards — the bucket-bar tab now gets the
  unread dot + 3-pulse when the user is looking at a different
  bucket. Own pushes are skipped (the relay echoes them back too).

gitea plugin: make ticket from card (public/plugins/gitea/gitea.js):
* New window._giteaMakeIssueFromCard(card) helper. Opens the gitea
  overlay, switches to the create-issue form, fetches the card body
  if it's lazy/null, and pre-fills #gitea-create-title and
  #gitea-create-body. Does NOT submit — the user picks the repo and
  reviews before clicking submit. Soft-bails on the welcome view
  if no gitea account is configured yet.

context-menu (public/js/modules/context-menu.js):
* New "Make ticket" entry in the card right-click menu, only rendered
  when window._giteaMakeIssueFromCard is exposed. Action handler
  hides the menu and calls the helper. Sits next to "Copy text".
* joinSelectedCards() now dedupes hashtag mentions in the merged body
  (first occurrence wins, case-insensitive) so a tag that appeared on
  multiple source cards isn't repeated in the resulting body. Followed
  by a tab/space/blank-line cleanup pass.

test runner auto-retry (public/plugins/tests/runner.js):
* runAll() takes an optional Set<string> of `${suite}::${test}` keys
  and runs only those when set. Progress bar denominator reflects
  the filtered count.
* run() collects every failed test after the first pass, restores the
  backup so the retry runs against the same baseline state, then
  re-runs only those via runAll(failedKeys). Retry results are merged
  into the original results array with `retried: true` and the
  original error preserved on `originalError`.
* renderResults distinguishes three states: passed first try (green ✓),
  pass-on-retry (amber ⚠ "flaky — passed on retry" with the first-run
  error shown), failed twice (red ✗ "failed twice"). Summary line
  carries a "N flaky" count and goes amber if only flaky tests
  appeared in the run.

tests (public/plugins/tests/context-menu.test.js):
* Two new tests for the make-ticket action:
  - action exists in the menu when window._giteaMakeIssueFromCard
    is exposed (soft-skip otherwise)
  - clicking it opens the gitea overlay, surfaces the create-issue
    form, and pre-fills title + body without submitting. Soft-skips
    the assertion when no gitea account is configured (welcome view).

chore: bump version to 0.9.7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 23:31:05 +02:00
thandClaude Opus 4.6 fe3399a44b tests: in-run progress strip + cache-bust runner.js across files
* runner.js: shows a 30px fixed-top progress strip during runs (label
  "test x/total:", current suite/test name with ellipsis on the left,
  fixed 50%-wide progress fill on the right that turns danger-red on
  the first failure). The DOM node is created in loader.js so it appears
  immediately on shortcut press; runner.js only updates it. The fill
  width is fixed at flex:0 0 50% so it doesn't jiggle as the test name
  changes length. Suites now live on window._testSuites as a defensive
  fallback so two runner instances stay in sync.

* Cache invalidation: every test file's `from './runner.js'` is now
  `from './runner.js?v=2'`, and loader.js imports the runner with the
  same RUNNER_V suffix. Same URL → one module instance → suite
  registration and runAll see the same array. Bumping RUNNER_V (in
  loader.js + every test file in lock-step) is the way to force a
  re-fetch when runner.js changes.

* loader.js: ensureProgressBar() draws the strip via setProperty(...,
  'important') with z-index 2147483647 attached to documentElement so
  nothing in user CSS, scanline overlay (z 9999) or modals can occlude
  it. Auto-run path (?test=1) also pre-renders the strip.

chore: bump version to 0.9.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:19:22 +02:00
thandClaude Opus 4.6 43c15b81a3 tests: rebind runner to Ctrl+Shift+Alt+T and cover recent fixes
Plugin loader + runner shortcut moves to Ctrl+Shift+Alt+T (the old
Ctrl+Shift+T conflicts with the browser "reopen closed tab"). Loader
now imports runner.js *without* the cache-busting query so it picks
up the same module instance the test files register their suites
into — previously the shortcut opened a fresh runner with an empty
suites array and reported 0/0 passed.

New / fixed coverage:
- card-interactions: favorite toggle assertion is now case-insensitive
  (context menu was capitalized to "Unfavorite"/"Favorite" earlier);
  done-badge test guards against state.hideDone / hideTagged that would
  filter the test card off the board; new test for the always-on
  Mark done / Unmark done toggle on a card without due_date.
- context-menu: copy-text action exists; copy-text strips fenced code
  blocks, image markdown and inline #tags. Mocks navigator.clipboard
  via Object.defineProperty so the assertion works without a focused
  / secure-context clipboard.
- export: round-trip preserves a custom bucket color (covers the import
  handler regression that was wiping bucket colors on every test run).
- theme: design preset selection persists in localStorage across
  settings open/close, refreshPresetSelect ignores unknown keys.
  afterEach restores both hyprcrd-design-active-preset and
  hyprcrd-design so a test run can't permanently swap the user's
  design.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:50:25 +02:00
th 1545b90f39 plugin infrastruktur 2026-04-10 07:57:53 +02:00