Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2526 +/- ##
==========================================
+ Coverage 78.29% 78.49% +0.19%
==========================================
Files 281 290 +9
Lines 20623 20898 +275
Branches 2109 2115 +6
==========================================
+ Hits 16147 16404 +257
- Misses 4428 4447 +19
+ Partials 48 47 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
pylipp
left a comment
There was a problem hiding this comment.
Hey @MomoRazor , thanks a lot for this large PR! I could do some functional testing, and I'm already quite happy with the new module. I found some small bugs, and I have some UX questions that I'm getting Roanna's feedback for.
Bugs
- table breaks when filtering Application for All and Box
- in the selection for columns displayed in the table, the first (checkbox) column should not be listed; it's always displayed
- when creating/updating a tag, and selecting "Boxes" or "Beneficiaries" as Application, I can't submit the form. Maybe a zod issue?
UX questions @aerinsol please let us know your preferences:
- Tags overview - action buttons: side by side on the same level as the table like in dropapp, or unfolding from a menu? Are the icons ok?
- Tags overview column name "Application". In dropapp it is "Apply to". Change it or keep it?
- UpdateTag title: "Update Tag # 57" . It contains the ID. In UpdateBox we show "Box 12345678" as title. I think "Update Tag" would be fine
- created/lastModified info: in dropapp, the tag details page shows a box with created and last-modified info. We don't have this in v2 but we could add the created/lastModified columns in the TagsOverview (but hide them by default)
- UpdateTag: when changing the Application to "Boxes" or "Beneficiaries", it would be nice to have an info text appear (like from the
iinfo icon in dropapp): "changing type will unassign tags applied to boxes" or "...to beneficiaries" - CreateTag: would be nice to have a random color picked
| const { createToast } = useNotification(); | ||
| const { triggerError } = useErrorHandling(); | ||
|
|
||
| const { data: tagData, error: tagError } = useSuspenseQuery(TAG_QUERY, { |
There was a problem hiding this comment.
I'm wondering if this query can be avoided since the data for the form could be taken from the row?
There was a problem hiding this comment.
Seeing as the Update Tag Form is a page right now, have you go any idea on how I can pass all the row information to a different page, rather then just pass the 'id' and pull the tag a new? Or should I consider the option of not having the update form in a completely separate link as it is now?
There was a problem hiding this comment.
Could you use the Apollo Cache maybe? When TagOverview is shown first, it should have all tags loaded by keys Tag:ID (I use the Apollo extension to view this in the browser dev tools).
If it's a cache miss for some reason (e.g. someone navigating directly to /tags/ID without having viewed TagOverview before), then the BE query should be run.
I haven't actually done this, it's an idea rather that would need a bit more investigation.
Re your question I'd keep the update form on a separate link.
|
@aerinsol some dropapp UX elements for reference: |
|
Thanks for the feedback @pylipp ! I'll probably get stuck in tomorrow :) |
|
Yeesh, I really don't like the interaction look for updating a tag. I know we use it for agreements and boxes but ugh. Doesn't seem to fit the tags - likely a good quick and dirty redesign task for Mariam. Nevertheless.... To answer your questions
Drop down is unnecessary here. I would keep it side by side so there's not an extra click.
Use the drop app name.
Agree.
Yes, would have this in the table. For the detailed view I would give it to Mariam.
Agree
Agree |
|
Hi guys! Quick update on this:
With those done, what remains are the following:
Let me know if I may have missed anything :) |
|
thanks for the update @MomoRazor |
There was a problem hiding this comment.
Pull request overview
Adds the new Tags module to the Boxtribute frontend (and supporting shared components / GraphQL cache updates) so coordinators can create, update, list, and delete tags in the new app UI.
Changes:
- Introduces Tag management pages (overview table, create, update) with routing + header menu entry.
- Adds tag deletion flow (bulk selection + confirmation) and a shared hex color picker field used by the tag form.
- Extends Tag GraphQL fragments / mocks / tests to include additional tag metadata fields (e.g., deletedOn / lastUsedOn) and updates Apollo cache policy for
Query.tag.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| shared-components/form/ColorField.tsx | New shared hex color picker input used by TagForm. |
| package.json | Adds a convenience rebuild-restart script. |
| graphql/fragments.ts | Formatting change to a fragment selection set. |
| front/src/views/Tags/UpdateTag/UpdateTagView.tsx | New “Update Tag” view + mutation handling. |
| front/src/views/Tags/UpdateTag/UpdateTagView.test.tsx | Tests for updating tags (success + error cases). |
| front/src/views/Tags/TagsOverview/TagsView.tsx | New “Manage Tags” overview page shell. |
| front/src/views/Tags/TagsOverview/TagsView.test.tsx | Tests for tags overview page behaviors (table, filtering, delete dialog, etc.). |
| front/src/views/Tags/TagsOverview/components/transformers.ts | Transforms tag query results into table rows. |
| front/src/views/Tags/TagsOverview/components/TagsTable.tsx | Tags table rendering with selection + actions. |
| front/src/views/Tags/TagsOverview/components/TagsContainer.tsx | Suspense query + column definitions + navigation wiring. |
| front/src/views/Tags/TagsOverview/components/TagsActions.tsx | Create/Delete actions above the table. |
| front/src/views/Tags/TagsOverview/components/RemoveTagsOverlay.tsx | Confirmation dialog UI for bulk tag deletion. |
| front/src/views/Tags/TagsOverview/components/RemoveTagsButton.tsx | Button + dialog state management for tag deletion. |
| front/src/views/Tags/hooks/useTagsActions.ts | Hook tying selected rows to tag actions (delete). |
| front/src/views/Tags/CreateTag/CreateTagView.tsx | New “Create Tag” view + mutation handling. |
| front/src/views/Tags/CreateTag/CreateTagView.test.tsx | Tests for creating tags (success + error cases). |
| front/src/views/Tags/components/TagForm.tsx | Shared Tag form with Zod validation + ColorField integration. |
| front/src/views/Tags/components/TagForm.test.tsx | Unit tests for TagForm validation and submission. |
| front/src/views/QrReader/QrReaderMultiBoxAssignTags.test.tsx | Updates mocks/timeouts due to Tag shape changes. |
| front/src/views/Boxes/BoxesViewActions.test.tsx | Updates tag mocks used by box bulk actions tests. |
| front/src/views/Boxes/BoxesView.test.tsx | Updates tag mocks + test timeouts to align with new Tag fields. |
| front/src/views/BoxEdit/BoxEditView.test.tsx | Increases timeout (likely to reduce flakiness). |
| front/src/tests/helpers.ts | Fixes async iteration in select-field helper. |
| front/src/queries/fragments.ts | Extends TagBasicFields fragment with new fields. |
| front/src/queries/cache.ts | Adds Query.tag typePolicy read to normalize tag queries. |
| front/src/mocks/tags.ts | Extends tag mocks with new fields used across tests. |
| front/src/mocks/boxes.ts | Extends embedded tag mocks inside box fixtures. |
| front/src/hooks/useDeleteTags.ts | New hook + mutation for deleting tags. |
| front/src/components/Table/Filter.tsx | Wraps popover content in a Portal for filter UI. |
| front/src/components/HeaderMenu/HeaderMenuContainer.tsx | Adds internal “Manage Tags” link in coordinator menu. |
| front/src/App.tsx | Adds routes for tags overview / create / update under base routes. |
| name: updateTagOutput.name, | ||
| type: updateTagOutput.application, | ||
| color: updateTagOutput.color, | ||
| description: updateTagOutput.description ?? "", |
There was a problem hiding this comment.
UpdateTagView forces description to "" when it’s undefined (updateTagOutput.description ?? ""). This will overwrite a previously-null/undefined description with an empty string even if the user didn’t touch the field. Prefer passing undefined when the field is unset (or explicitly decide on a clear 'clear description' behavior) to avoid unintended data changes.
| description: updateTagOutput.description ?? "", | |
| description: updateTagOutput.description, |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Philipp Metzner <10617122+pylipp@users.noreply.github.com>
…ocal state Agent-Logs-Url: https://github.com/boxwise/boxtribute/sessions/ac47d3d1-0c84-4718-adef-2baa6d82e39a Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
|
@copilot try to fix two more issues:
|
Agent-Logs-Url: https://github.com/boxwise/boxtribute/sessions/371ba24f-70d8-44c6-9a8b-cb87a9dfd4c0 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Fixed in Sticky header ( Date sorting ( |
|
@copilot when a new tag is created it has null lastUsedOn, and the sorting breaks. This must not happen |
…lumns Agent-Logs-Url: https://github.com/boxwise/boxtribute/sessions/99eb4e63-2f0c-474e-b952-3d7c22aa4ffb Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Fixed in Replaced all three date column sort types with a custom function nullableDateSortType(rowA, rowB, columnId) {
const a = rowA.values[columnId];
const b = rowB.values[columnId];
if (!a && !b) return 0;
if (!a) return 1; // null → end
if (!b) return -1;
return a.getTime() - b.getTime();
}Also fixed a related pre-existing TS error in |


Three bugs in the Tags overview table: header not sticky, date columns not sorting, and a crash when sorting tags with null dates.
Sticky header (
TagsTable.tsx)<Flex overflowX="auto">created a new scroll container, scoping<Thead position="sticky">to a container that never scrolled vertically. Changed outer Flex toheight="100%"(matchesBoxesTable) and movedoverflowX="auto"to a<Box>wrapping only<Table>.Date column sorting (
TagsContainer.tsx)All three date columns used
sort: "datetime"— not a react-table v7 column property. Changed tosortType: "datetime".Null date sort crash (
TagsContainer.tsx)react-table's built-in
"datetime"sort calls.getTime()unconditionally, throwingTypeErrorwhenlastUsedOn(or other date fields) isnullon a newly created tag. Replaced with a custom sort function that pushes nulls to the end:Pre-existing TS error (
transformers.ts)lastModifiedOnfallback wasnew Date(createdOn)—createdOncan benull, causing a type error. Changed toundefinedwhen both are null, consistent with howlastUsedOnis handled.