Project board header toolbar revamp - EXO-88315 - #625
Conversation
## What Reworks the project board header toolbar to be compact and responsive, modelled on the **Agenda / Documents** toolbars, and makes task search usable on mobile. Before, the header used a hand-rolled `v-toolbar` with an inline `v-tabs` view switcher, an always-on keyword field and a separate *Filter* button, laid out with a fixed 30 % / 70 % flex split plus bespoke `@media` CSS that simply **hid the keyword search on small screens**. ## Changes - Breadcrumb (back link + project name) stays on the left; the `task-board-header` extension point (favorite ⭐ / AI 🔔) moves to the **right**, grouped with the other actions. - The **Board / List / Plan** view selector becomes a compact icon + dropdown menu — new `TasksViewSwitcher`, styled after agenda's `AgendaSwitchView` — kept visible on mobile. - The **keyword search** collapses behind a filter icon and expands **full width** with a back arrow (Esc closes it) → search now works on phones. - The **advanced filter** keeps its own icon (with applied-filter count) and opens the existing *Sort & Filter* drawer. - Right-hand action order: favorite/AI · view selector · search · advanced filter. All icons are `36×36 / 20px` with the lighter `text-light-color`, evenly spaced; the back arrow aligns with the first column's content. - The view-switcher dropdown is relocated into the Vuetify app root so it renders above the kanban board with the correct (opaque) theme background. - Removes the now-dead toolbar CSS (30/70 flex split, view-tab styling, mobile overrides). No backend changes. New i18n key `label.viewOptions` (en only; Crowdin syncs the rest). ## Test Verified live on a Meeds 7.2.x server: Board/List/Plan switching, full-width search expand/collapse (incl. narrow widths), advanced filter drawer, favorite/AI icons, alignment and even spacing — desktop and compact. --------- Co-authored-by: Benjamin <benjmestrallet@MacBook-Air.local> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Benjamin <benjmestrallet@mac.home> Co-authored-by: Ali HAMDI <ahamdi@exoplatform.com> (cherry picked from commit 77fd6dc)
boubaker
left a comment
There was a problem hiding this comment.
Reviewed the diff, the current state of the touched files on backport/EXO-88315-board-toolbar, cross-checked against TasksListToolbar.vue (already merged via #623) and the cited AgendaSwitchView.vue precedent in exoplatform/agenda, and checked SonarCloud's new issues for this PR.
Overview
Backport of #616: reworks the project board header into a compact, responsive toolbar (breadcrumb left, favorite/AI + view switcher + search + advanced filter grouped right), replacing the old v-tabs-based view selector with a new TasksViewSwitcher dropdown and making keyword search collapsible/full-width on mobile. All CI checks pass, including SonarCloud this time.
Main finding — TasksViewSwitcher reinvents what <v-menu> already does
The PR says it's "styled after agenda's AgendaSwitchView" — I pulled that component (exoplatform/agenda's agenda-webapps/.../top-toolbar/AgendaSwitchView.vue) to compare. It's a plain <v-menu offset-y close-on-click> with an #activator slot — no manual DOM manipulation.
TasksViewSwitcher.vue instead hand-rolls the same behavior: it moves the dropdown card to .v-application via appendChild, computes top/left from getBoundingClientRect() on open, and manages its own click/scroll listeners to close it. This is exactly what <v-menu> already does out of the box (it renders its content detached from the DOM flow specifically to escape ancestor stacking contexts) — the stated reason ("not trapped in a v-toolbar stacking context" / kanban board's 3D-transform compositing layers) is the textbook case <v-menu> is built to handle, and its own cited precedent doesn't need to work around it.
Side effects of the manual approach, all of which come for free with <v-menu>:
- No Escape-to-close on the switcher (the search field gets
@keydown.esc, the switcher doesn't). - Most of
.tasksViewSwitcherMenu's CSS is dead on arrival:position: absolute,top,inset-inline-endandz-index: 1000are all immediately overridden by the inline styles set inmounted()/positionMenu()(which usefixed, computedtop/left, andzIndex: 9999). Onlytransform: translateZ(0)and the duplicatemin-widthactually matter at runtime..tasksViewSwitcher { position: relative; }is similarly pointless once the child is reparented to.v-applicationwithposition: fixed.
Would suggest trying a plain <v-menu offset-y> first (matching AgendaSwitchView) and only reaching for the manual DOM-relocation approach if there's a concrete, reproducible issue with it inside the kanban board — in which case that's worth a one-line comment explaining what broke, so the next reader doesn't wonder why this component diverges from its own stated model.
Confirmed by SonarCloud (3 new MAJOR issues)
TasksViewSwitcher.vue:changeevent triggered but not declared inemits.TasksViewToolbar.vue:keyword-changedevent triggered but not declared inemits.TasksViewSwitcher.vue:103: preferchildNode.remove()overparentNode.removeChild(childNode).
All three go away if the <v-menu> simplification above is adopted (removes the manual DOM node teardown entirely) plus a one-line emits fix on the toolbar.
Checked and NOT a regression
.tasksToolbar(and its.taskDisplay/.taskTabBoard/.taskTabList/.taskTabGantt/.projectTasksViewTabschildren) is removed fromtasks.less— verified its only consumer was thev-tabsmarkup this PR itself replaces inTasksViewToolbar.vue, so no orphaned-class situation like the one from #623's original cleanup.- Dropping the
resetFields('query')call from the keyword-change handler (so typing a search term no longer wipes the other active advanced filters) matches the behavior already shipped in the siblingTasksListToolbar.vuevia #623 — consistent, not an accidental side effect of this rewrite.
Minor
<v-text-field v-model="keyword" ... @input="onKeyword">:v-modelalready assignsthis.keywordon input;onKeywordreassigns the same value again before debouncing. Harmless, just redundant.
- TasksViewSwitcher: replace manual DOM-relocation dropdown (appendChild, getBoundingClientRect positioning, click/scroll listeners) with a plain v-menu, matching the AgendaSwitchView precedent this PR was modeled on. v-menu already escapes the kanban board's stacking context on its own. - Declare emits (`change` on the switcher, `keyword-changed` on the toolbar) to fix the two Sonar-flagged undeclared-emit issues. - Drop the now-dead absolute-positioning CSS this replaces; keep only the menu's min-width as a standalone rule (v-menu content isn't nested under .projectBoardToolbar). - Remove the redundant this.keyword reassignment in onKeyword (v-model already sets it). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
Thanks for the detailed review @boubaker — addressed all points in eea931c: Main finding — Sonar's 3 new MAJOR issues
Dead CSS Minor — redundant Verified after the change: eslint clean on both touched files, and |
boubaker
left a comment
There was a problem hiding this comment.
Verified the fix commit (eea931c3) directly, not just the commit message:
TasksViewSwitcher.vuenow uses a plain<v-menu v-model offset-y close-on-click>with an#activatorslot, matchingAgendaSwitchView's pattern exactly — all the manual DOM-relocation/positioning/listener code is gone.emits: ['change']/emits: ['keyword-changed']added, clearing both Sonar-flagged undeclared-emit issues.- Dead CSS trimmed:
.tasksViewSwitcher { position: relative }removed,.tasksViewSwitcherMenureduced to a standalonemin-width: 160pxrule (correctly moved out of.projectBoardToolbarnesting, since v-menu's content is teleported and wouldn't match the old nested selector anymore). onKeywordno longer redundantly reassignsthis.keyword(v-modelalready does it) — confirmed the debounced$emitstill reads the right value.
CI is green (PR Build, SonarCloud, Snyk) and SonarCloud's open-issue list for this PR is now empty.
Approving.



What
Backport of #616 (squash-merged into
feature/ai-contribution) ontodevelop.Reworks the project board header toolbar to be compact and responsive (modelled on the Agenda/Documents toolbars), and makes task search usable on mobile:
TasksViewSwitcher, new component).Backport notes
Cherry-picked cleanly on top of the current
develop(which since diverged and now includes #623 "Tasks UI revamp — project cards & list toolbars").#623touchedtasks.less/ProjectCard*/ProjectListToolbar/TasksListToolbarbut never touchedTasksViewToolbar.vueortasksViewSwitcher/projectBoardToolbarCSS selectors, so there's no functional overlap between the two — auto-merge only needed to interleave unrelated hunks in shared files (tasks.less,taskManagement_en.properties,initComponents.js).Verified after cherry-pick:
TasksViewSwitcher.vue/TasksViewToolbar.vueclass names (tasksViewSwitcher,tasksViewSwitcherMenu,projectBoardToolbar,boardHeaderExtensions) all still resolve against the currenttasks.less(post-feat: Tasks UI revamp — project cards & list toolbars - EXO-88314 #623 restructuring).initComponents.js, no duplicate/missing entries.Test
npx webpack --config webpack.prod.js --mode production→ compiled with 0 errors (pre-existing lint warnings only, unrelated to this change).🤖 Generated with Claude Code