ENG-699: Migrate privacy experiences table to Ant Design#7789
ENG-699: Migrate privacy experiences table to Ant Design#7789
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
15f7a98 to
3bfe23e
Compare
There was a problem hiding this comment.
Code Review: Privacy Experiences Table → Ant Design Migration
This is a clean, well-structured migration. The extraction of table logic into usePrivacyExperiencesTable is a clear improvement in separation of concerns, and the new getRegionValues using flatMap is more readable than the old forEach+push pattern. The try/finally fix in EnablePrivacyExperienceCell is a nice correctness improvement.
Issues
Bug (medium): Empty state button ignores permissions
The EmptyTableExperience component always renders the "Create new experience" button regardless of the user's PRIVACY_EXPERIENCE_UPDATE scope. In the main component the action bar is correctly gated behind userCanUpdate, but the empty-state path bypasses this check. See inline comment.
Nit: Duplicate keys in Properties column
Properties are keyed by p.name. If two properties share a name, React will warn about duplicate keys. See inline comment.
Nit: JSX element in memoized config
Minor referential stability concern with <EmptyTableExperience /> inside the antTableConfig memo. Not a blocker. See inline comment.
Other observations
PRIVACY_NOTICE_REGION_MAPremoval is safe — it was only consumed in the now-replacedgetRegionshelper.ComponentCellremoval fromcells.tsxexports is clean — it was only used insidePrivacyExperiencesTableitself.- The Cypress test update from
data-testid="row-N"tocy.get("table").contains("tr", item.name)is the right approach for Ant Design tables. updated_atrendered vianew Date(updated_at).toDateString()is consistent with the prior implementation, so no regression there.
| iconPosition="end" | ||
| > | ||
| Create new experience | ||
| </Button> |
There was a problem hiding this comment.
The "Create new experience" button inside EmptyTableExperience is always rendered regardless of the user's permissions. In the main component, the action bar (including the equivalent button) is gated behind userCanUpdate. A user without PRIVACY_EXPERIENCE_UPDATE scope will see this button in the empty state and be able to click it, even though they shouldn't be able to create experiences.
Consider passing userCanUpdate as a prop to EmptyTableExperience (or moving the component definition inside the hook where that value is available) and either hiding the button or rendering a permission-aware version:
const EmptyTableExperience = ({ canCreate }: { canCreate: boolean }) => {
...
{canCreate && (
<Button onClick={...} ...>
Create new experience
</Button>
)}
...
};| columnState={{ isExpanded: isPropertiesExpanded }} | ||
| /> | ||
| ), | ||
| menu: { |
There was a problem hiding this comment.
Properties are keyed by p.name, which means two properties with the same name will produce duplicate React keys and a console warning. Consider using a stable unique identifier (e.g. p.id if available) as the key, or a composite like ${p.id}-${p.name} as a fallback:
values={(properties ?? []).map((p) => ({
label: p.name,
key: p.id ?? p.name,
}))}| ]); | ||
|
|
||
| const tableState = useTableState({ | ||
| pagination: { |
There was a problem hiding this comment.
antTableConfig is memoized but <EmptyTableExperience /> is created as a new JSX element on every render. While EmptyTableExperience itself is stable (module-level), the element is re-created whenever the memo re-runs. This is low-impact but if you want strict referential stability you can define it once outside the memo:
const emptyText = useMemo(() => <EmptyTableExperience />, []);
const antTableConfig = useMemo(
() => ({
...
customTableProps: { locale: { emptyText } },
}),
[dataSource, totalRows, isLoading, isFetching, emptyText],
);(Not a blocker — just a nit if consistency with the rest of the memo pattern matters.)
Ticket ENG-699
Description Of Changes
Migrates the Privacy Experiences table from the legacy
FidesTableV2(TanStack-based) component to the new Ant Design table infrastructure, consistent with other recently migrated tables in the admin UI.Code Changes
usePrivacyExperiencesTablehook, returningtablePropsandcolumnsfor use with the Ant<Table>componentFidesTableV2row/cell rendering with Ant Design column definitions in the hookPRIVACY_NOTICE_REGION_MAP(Map) fromprivacy-notice-regions.tsin favor of directPRIVACY_NOTICE_REGION_RECORDlookupdata-testid="row-${index}"(which was specific to the old table), and addeddata-testid="empty-state"to the empty state componentEnablePrivacyExperienceCellby wrapping the mutation intry/finallySteps to Confirm
Pre-Merge Checklist
CHANGELOG.mdupdatedmaindowngrade()migration is correct and works