feat: Tasks UI revamp — project cards & list toolbars - EXO-88314 - #623
Conversation
8737e41 to
62c5dee
Compare
boubaker
left a comment
There was a problem hiding this comment.
Reviewed the diff and cross-checked the actual template/CSS state on backport/EXO-88314-develop, plus the shared application-toolbar component contract from Meeds-io/social. This is a large, mostly-frontend revamp (project cards, list toolbars, CSS cleanup) — overall direction is good (removing the flip-card design, jQuery width hacks, and duplicated color/chip CSS in favor of shared components), but there's one confirmed visual regression.
Confirmed bug — dead CSS still referenced by the Gantt view
tasks.less removes the .unscheduled-task-container / .unscheduled-task-btn / .unscheduled-task-badge rules (absolute positioning, FAB background, badge circle styling), but TasksViewGantt.vue still renders exactly those classes for the floating "unscheduled tasks" button + counter badge (confirmed both the removed CSS and the still-present markup on the PR branch). Without the CSS, that button loses its floating position and the badge its circle styling in the Gantt tab. Looks like this got swept up in the broader "remove dead flip-card CSS" cleanup by mistake — this block is unrelated to the project-card flip removal.
Performance — eager per-card stats fetch
ProjectCardFront.vue now calls getStatusesByProjectId() + getProjectStats() in mounted() unconditionally for every rendered card, to feed the new progress-bar footer. A page of 20 project cards fires ~40 parallel REST calls on load. The previous design (ProjectCardReverse.vue, now deleted) only fetched stats lazily when a card was flipped by the user. Worth considering lazy-loading (e.g. only once a card is visible) or a batched stats endpoint, especially since a similar N+1 pattern was just fixed on the backend side for favorites in PR #622.
Known limitation, self-documented — client-side "Favorites" project filter
ProjectCardList.vue's displayedProjects filters the already-paginated projects array by .favorite when projectFilterSelected === 'FAVORITES', since ProjectRestService.getProjects has no FAVORITES branch server-side (confirmed). canShowMore is based on the unfiltered count, so a user with few favorites scattered across many projects may need to click "Load more" repeatedly before seeing them all. Not a crash, and the code comment already flags it as a deliberate workaround — but a real backend filter (could reuse FavoriteUtil.getFavoriteObjectIds from PR #622) would fix both the UX and the wasted client-side fetch/filter.
Good
application-toolbarreuse inProjectListToolbar.vue/TasksListToolbar.vue: verified the props (left-button,right-text-filter,right-select-box,right-filter-button,filters-count,compact) and events (left-button-click,filter-text-input-end-typing,filter-select-change,filter-button-click) against the actual shared component inMeeds-io/social— all match. Nice cleanup of the old per-component jQuery width/select hacks.- Row-level
@click="openTaskDrawer()"+ targeted@click.stoponTaskViewListItem.vue's checkbox/assignee cells is consistent and doesn't leave any inner clickable element mis-firing the row handler. - No backend/Java changes, no new files, so no license-header concerns here.
CI note
"Analyse Project with SonarCloud" is failing, but on a transient infra error (Failed to query JRE metadata: ... HTTP 504 Gateway Timeout from SonarCloud's own API) — unrelated to this diff, should clear on re-run. "PR Build" and Snyk both pass.
- Restore .unscheduled-task-container/-btn/-badge rules in tasks.less, dropped by mistake in the flip-card CSS cleanup — TasksViewGantt.vue still renders these classes for the floating unscheduled-tasks button. - ProjectCardFront.vue: fetch project stats only once a card scrolls into view (IntersectionObserver) instead of unconditionally for every card on mount, avoiding ~40 parallel REST calls on a 20-card page. Addresses review comments on #623.
|
Thanks for the review — addressed in 4f9ae27:
Left the client-side "Favorites" filter as-is for now since it's flagged as a non-blocking, self-documented workaround rather than a bug — happy to follow up with a real backend filter (reusing Ready for re-review. |
The short-circuit `this.statsObserver && this.statsObserver.disconnect()` statement failed the PR Build's eslint pass; use an explicit if instead.
tasks.less: restore the .tasksToolbar block (.inputTasksFilter, .taskFilterMobile, .selectPrimaryFilter, .selectTasksFilter, .taskDisplay, .taskTabCards, .taskTabList, .filterTasksSetting, ...), removed in the same dead-CSS cleanup as the Gantt unscheduled-task styles already fixed in 4f9ae27. TasksViewToolbar.vue (the toolbar on a project's task board/list/gantt view) was left untouched by this PR and still renders every one of these classes — without them the card/list view toggle tabs, filter input and filter-settings button lose their styling. Checked every other class removed from tasks.less in this PR against the current templates: the color-swatch classes still have their own top-level rule untouched, and .spaceAvatar/.noProjectColor only lost now-unused nested/override rules whose templates were rewritten in this same PR, so nothing else regresses. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Follow-up after the fix commits:
No other missing class found after checking the full removed-class list against the current template tree. |
The scanner's JRE auto-provisioning call to api.sonarcloud.io/analysis/jres has been returning HTTP 504 Gateway Timeout, failing the Sonar Analysis check before any actual analysis runs. Reuse the JDK already set up by actions/setup-java instead of downloading one from SonarCloud. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
boubaker
left a comment
There was a problem hiding this comment.
All the issues raised are now fixed:
- Gantt
.unscheduled-task-containerCSS regression — fixed - Eager per-card stats fetch (~40 parallel REST calls on a 20-card page) — fixed with an IntersectionObserver-based lazy fetch
- The ESLint
no-unused-expressionserror that brokePR Buildon the fix commit — fixed .tasksToolbarCSS regression affectingTasksViewToolbar.vue(missed in the first pass, found while double-checking every removed class against the current templates) — fixed and verified with a localmvn -pl webapps -am install(LESS compile + webpack/eslint green)
PR Build (the only required check on develop) is green. Analyse Project with SonarCloud is failing on an unrelated, transient HTTP 504 Gateway Timeout from SonarCloud's own JRE-provisioning API — not a code issue.
Remaining known limitation: the "Favorites" project filter is client-side only (no backend filter yet), already self-documented in the code as a deliberate trade-off — not blocking.
Note: some of the fixes above (the .tasksToolbar CSS restoration, commit ecedb15) were contributed directly by me to this branch. Approving with the author's explicit awareness/confirmation of that.
Approving.
## What Backport of #616 (squash-merged into `feature/ai-contribution`) onto `develop`. Reworks the project board header toolbar to be compact and responsive (modelled on the Agenda/Documents toolbars), and makes task search usable on mobile: - Board/List/Plan view selector becomes a compact icon + dropdown (`TasksViewSwitcher`, new component). - Keyword search collapses behind a filter icon and expands full width (works on phones now). - Advanced filter keeps its own icon with an applied-filter count. - Removes the now-dead 30/70 toolbar CSS split and old tab styling. ## 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"). `#623` touched `tasks.less`/`ProjectCard*`/`ProjectListToolbar`/`TasksListToolbar` but never touched `TasksViewToolbar.vue` or `tasksViewSwitcher`/`projectBoardToolbar` CSS 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.vue` class names (`tasksViewSwitcher`, `tasksViewSwitcherMenu`, `projectBoardToolbar`, `boardHeaderExtensions`) all still resolve against the current `tasks.less` (post-#623 restructuring). - Component registered once in `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](https://claude.com/claude-code)
(cherry picked from commit b14b8a2)