fix: address taxa-list PR review feedback#1119
fix: address taxa-list PR review feedback#1119mihow wants to merge 10 commits intofeat/taxa-listsfrom
Conversation
…e and cache key, table loading state - entity.ts: createdAt getter was guarding on updated_at instead of created_at - utils.ts: revert project_id back to project; existing serializers (Device, Site, StorageSource, SourceImageCollection) declare the field as project - useTaxaListDetails: generic was TaxaList (client shape) instead of ServerTaxaList (raw API shape); added projectId to queryKey to avoid cross-project cache hits - taxa-list-details: isLoading on Table was gated on !id which is always falsy (id is a route param), so the loading state never showed Co-Authored-By: Claude <noreply@anthropic.com>
… tests TaxaListTaxonViewSet had permission_classes = [] (open to everyone). Set to IsActiveStaffOrReadOnly to match the parent TaxaListViewSet pattern. Test setUp now creates users with is_staff=True so POST/DELETE pass the permission check. Co-Authored-By: Claude <noreply@anthropic.com>
- TaxonTaxaListFilter docstring: include_descendants default was documented as false but the code defaults to True; corrected docs to match - get_taxa_list: added "from None" to suppress chained DoesNotExist traceback in the NotFound exception - create: replaced Taxon.objects.get with get_object_or_404 to close the race between serializer validation and the lookup - added get_object_or_404 import Co-Authored-By: Claude <noreply@anthropic.com>
- taxa-list-details: wrap AddTaxaListTaxonPopover in canUpdate check so users without write permission do not see the add button - add-taxa-list-taxon: disable the Add button while the mutation is in flight to prevent duplicate submissions - remove-taxa-list-taxon-dialog: disable the Confirm button while the remove mutation is in flight - taxa-lists: use the paginated total from the API instead of the length of the current page for the results count Co-Authored-By: Claude <noreply@anthropic.com>
- language.ts: rename MESSAGE_MESSAGE_REMOVE_TAXA_LIST_TAXON_CONFIRM to MESSAGE_REMOVE_TAXA_LIST_TAXON_CONFIRM (duplicated prefix); update enum key, translation map entry, and the one usage site - new-entity-dialog.tsx: remove unused API_ROUTES import - useSidebarSections.tsx: remove expression that computes a value but never assigns or returns it - breadcrumbs.tsx: add setMainBreadcrumb to useEffect dependency array Co-Authored-By: Claude <noreply@anthropic.com>
When e.preventDefault() stops Radix's default focus behaviour the dialog has no focused element, which breaks keyboard navigation and screen readers. Explicitly focus the dialog content after preventing the default in all three sites: taxa-list-details, species, and occurrences. Co-Authored-By: Claude <noreply@anthropic.com>
IsActiveStaffOrReadOnly blocks any non-staff user from POST/DELETE, but the intent of taxa lists is that any project member can manage them. Added IsProjectMemberOrReadOnly to ami/base/permissions.py: safe methods are open; unsafe methods check project.members via the active project resolved by ProjectMixin.get_active_project(). Reverted test users back to plain create_user — Project.objects.create with owner= auto-adds the owner as a member via ensure_owner_membership, which is all the permission now requires. Co-Authored-By: Claude <noreply@anthropic.com>
✅ Deploy Preview for antenna-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- get_taxa_list() now validates that the taxa list belongs to the active project, preventing cross-project manipulation via URL params - Added setDetailBreadcrumb to useEffect dependency array Co-Authored-By: Claude <noreply@anthropic.com>
| ...(description ? { description } : {}), | ||
| ...(name ? { name } : {}), | ||
| project_id: projectId, | ||
| project: projectId, |
There was a problem hiding this comment.
This change seems risky, I will revert
|
|
||
| get createdAt(): string | undefined { | ||
| if (!this._data.updated_at) { | ||
| if (!this._data.created_at) { |
| onOpenAutoFocus={(e) => { | ||
| /* Prevent tooltip auto focus */ | ||
| e.preventDefault() | ||
| ;(e.currentTarget as HTMLElement).focus() |
There was a problem hiding this comment.
If we want to enable auto focus again, the correct way would be to skip onOpenAutoFocus. The code in this method will now first disable, then enable again, so a bit unnecessary.
I disabled it because I was annoyed to see the rank tooltip show up on focus :) However it's better for accessibility to have it, so maybe not a good idea.
I'll push an update here.
| <FormSection | ||
| title={translate(STRING.REMOVE_TAXA_LIST_TAXON)} | ||
| description={translate( | ||
| STRING.MESSAGE_MESSAGE_REMOVE_TAXA_LIST_TAXON_CONFIRM |
| title={translate(STRING.NAV_ITEM_TAXA_LISTS)} | ||
| subTitle={translate(STRING.RESULTS, { | ||
| total: taxaLists?.length ?? 0, | ||
| total: total ?? taxaLists?.length ?? 0, |
There was a problem hiding this comment.
This can actually be simplified further now when we have pagination support!
|
Thanks for the fixes @mihow !! I pushed some tweaks and also tested things out again here. One thing I noticed in this branch is that if I'm a superuser, but not a member of the project, I cannot add or remove taxa from lists. This is not the case in the branch
|
Interesting discovery! I will look over the permissions for taxa lists as a whole again. I like the error handling you have now! "You do not have permission to perform this action" in the bar above the Add Taxon form! That is slick. I also opened this ticket to look more into permissions for all data types that can be assigned to multiple projects. |


Summary
Addresses review feedback (mihow, Copilot, CodeRabbit) on the taxa-lists feature branch. Grouped into six logical commits.
Bug fixes
entity.ts—createdAtgetter was guarding onupdated_atinstead ofcreated_atutils.ts— revertedproject_idback toproject; existing serializers (Device, Site, StorageSource, SourceImageCollection) all declare the field asprojectuseTaxaListDetails.ts— generic type changed fromTaxaList(client shape) toServerTaxaList(raw API shape); addedprojectIdto query key to prevent cross-project cache collisionstaxa-list-details.tsx— TableisLoadingwas gated on!idwhich is always falsy (route param), so loading state never showedSecurity / permissions
IsProjectMemberOrReadOnlypermission class (ami/base/permissions.py). Safe methods are open; unsafe methods (POST/DELETE) require the user to be a member of the active project. Scoped tighter thanIsActiveStaffOrReadOnly(which blocks non-staff project members) and looser than guardian object-level perms (which don't cover M2M-to-project models like TaxaList).TaxaListTaxonViewSet— waspermission_classes = [](completely open).Backend cleanup
TaxonTaxaListFilterdocstring corrected:include_descendantsdefaults totrue, notfalseget_taxa_list: addedfrom Noneto suppress chainedDoesNotExisttracebackcreate: replacedTaxon.objects.getwithget_object_or_404to close the race between serializer validation and the lookupUX
canUpdate(the per-row remove button already was)totalfrom the API instead of current-page lengthNaming / dead code
MESSAGE_MESSAGE_REMOVE_TAXA_LIST_TAXON_CONFIRM→MESSAGE_REMOVE_TAXA_LIST_TAXON_CONFIRMAPI_ROUTESimport innew-entity-dialog.tsxuseSidebarSections.tsx(computed value never used)setMainBreadcrumbtouseEffectdep array inbreadcrumbs.tsxAccessibility
taxa-list-details,species,occurrences) callede.preventDefault()inonOpenAutoFocuswithout transferring focus. Added explicit.focus()on the dialog content in each.Test plan
ami.main.tests.TaxaListTaxonAPITestCaseandTaxaListTaxonValidationTestCase— all 13 pass with non-staff project-member users