Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PROD-1667 Link properties and experiences #4658

Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
cca8ef2
Adding edit functionality for properties
galvana Feb 29, 2024
b655e92
Adding experiences form section
galvana Mar 1, 2024
630ecbf
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 1, 2024
b5e3e18
Linking properties and privacy experiences in the database
galvana Mar 4, 2024
81d172c
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 5, 2024
3e83323
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 5, 2024
cdd7e3d
Bidirectional linking of properties and privacy experiences
galvana Mar 5, 2024
00d9335
Removing properties from history data
galvana Mar 5, 2024
1f87ea2
Misc fixes
galvana Mar 6, 2024
d98578b
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 6, 2024
c83829d
Fixing downrev
galvana Mar 6, 2024
34bf8be
Updating Cypress fixtures
galvana Mar 6, 2024
79f246d
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 6, 2024
300545f
Updating fides dataset
galvana Mar 6, 2024
bf3420b
Fixing downrev
galvana Mar 6, 2024
60fe537
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 6, 2024
23aeded
Adding property column to experiences table
galvana Mar 7, 2024
fb4bdf3
Resizing experience table buttons
galvana Mar 7, 2024
0969e47
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 7, 2024
cdff362
Updating schema
galvana Mar 7, 2024
e94e0eb
Fixing test
galvana Mar 7, 2024
e1d3f98
Updating Cypress fixtures
galvana Mar 7, 2024
5a98d9b
Adding property to experience fixture
galvana Mar 7, 2024
8366376
Updating UI permissions
galvana Mar 7, 2024
e673f65
Fixing update bug
galvana Mar 8, 2024
40be6d2
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 8, 2024
deae93e
Removing unused button
galvana Mar 8, 2024
8e56123
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 8, 2024
b659260
Removing unused import
galvana Mar 8, 2024
f07df1d
Updating Fides JS script template
galvana Mar 11, 2024
490bbc1
Merge branch 'PROD-1458_multi_language_support' into PROD-1667-link-p…
galvana Mar 11, 2024
8b9bdbf
Fixing migration comment and updating change log
galvana Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .fides/db_dataset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2047,3 +2047,15 @@ dataset:
data_categories: [system.operations]
- name: updated_at
data_categories: [system.operations]
- name: plus_privacy_experience_config_property
fields:
- name: id
data_categories: [system.operations]
- name: privacy_experience_config_id
data_categories: [system.operations]
- name: property_id
data_categories: [system.operations]
- name: created_at
data_categories: [system.operations]
- name: updated_at
data_categories: [system.operations]
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"version": 3.0,
"created_at": "2023-05-30T23:42:10.300484+00:00",
"updated_at": "2023-05-31T00:28:24.694384+00:00",
"regions": []
"regions": [],
"properties": []
},
{
"name": "notice disabled test",
Expand All @@ -42,7 +43,8 @@
"version": 2.0,
"created_at": "2023-05-30T23:40:11.459287+00:00",
"updated_at": "2023-05-31T00:39:29.906976+00:00",
"regions": ["us_ca"]
"regions": ["us_ca"],
"properties": [{ "id": 1, "name": "Property A" }]
}
],
"total": 2,
Expand Down
8 changes: 5 additions & 3 deletions clients/admin-ui/cypress/fixtures/properties/properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
{
"name": "Property A",
"type": "Website",
"key": "property_a"
"id": "FDS-CEA9EV",
"experiences": [{ "id": 1, "name": "US Privacy Center" }]
},
{
"name": "Property B",
"type": "Other",
"key": "property_b"
"type": "Website",
"id": "FDS-Z21I5X",
"experiences": [{ "id": 1, "name": "US Privacy Center" }]
}
],
"total": 2,
Expand Down
2 changes: 2 additions & 0 deletions clients/admin-ui/src/app/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { languageSlice } from "~/features/privacy-experience/language.slice";
import { privacyExperienceConfigSlice } from "~/features/privacy-experience/privacy-experience.slice";
import { privacyNoticesSlice } from "~/features/privacy-notices/privacy-notices.slice";
import { subjectRequestsSlice } from "~/features/privacy-requests";
import { propertySlice } from "~/features/properties";
import { systemSlice } from "~/features/system";
import { dictSuggestionsSlice } from "~/features/system/dictionary-form/dict-suggestion.slice";
import { taxonomySlice } from "~/features/taxonomy";
Expand Down Expand Up @@ -84,6 +85,7 @@ const reducer = {
[organizationSlice.name]: organizationSlice.reducer,
[privacyNoticesSlice.name]: privacyNoticesSlice.reducer,
[privacyExperienceConfigSlice.name]: privacyExperienceConfigSlice.reducer,
[propertySlice.name]: propertySlice.reducer,
[subjectRequestsSlice.name]: subjectRequestsSlice.reducer,
[systemSlice.name]: systemSlice.reducer,
[taxonomySlice.name]: taxonomySlice.reducer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const CustomAssetUploadButton: React.FC<CustomAssetUploadButtonProps> = ({
<>
<Button
variant="outline"
size="sm"
size="xs"
ml={2}
onClick={uploadCustomAssetModal.onOpen}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const JavaScriptTag = () => {
<Button
onClick={modal.onOpen}
variant="outline"
size="sm"
size="xs"
rightIcon={<CopyIcon />}
data-testid="js-tag-btn"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Property } from "~/types/api";

const PRIVACY_CENTER_HOSTNAME_TEMPLATE = "{privacy-center-hostname-and-path}";
const PROPERTY_UNIQUE_ID_TEMPLATE = "{property-unique-id}";
const FIDES_JS_SCRIPT_TEMPLATE = `<script src="https://${PRIVACY_CENTER_HOSTNAME_TEMPLATE}/fides.js?${PROPERTY_UNIQUE_ID_TEMPLATE}"></script>`;
const FIDES_JS_SCRIPT_TEMPLATE = `<script src="https://${PRIVACY_CENTER_HOSTNAME_TEMPLATE}/fides.js?property_id=${PROPERTY_UNIQUE_ID_TEMPLATE}"></script>`;
const FIDES_GTM_SCRIPT_TAG = "<script>Fides.gtm()</script>";

interface Props {
Expand All @@ -43,7 +43,7 @@ const NewJavaScriptTag = ({ property }: Props) => {
const fidesJsScriptTag = useMemo(() => {
const script = FIDES_JS_SCRIPT_TEMPLATE.replace(
PROPERTY_UNIQUE_ID_TEMPLATE,
property.key!.toString()
property.id.toString()
);
if (isFidesCloud && isSuccess && fidesCloudConfig?.privacy_center_url) {
script.replace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ import {
selectPageSize as selectNoticePageSize,
useGetAllPrivacyNoticesQuery,
} from "~/features/privacy-notices/privacy-notices.slice";
import {
selectAllProperties,
selectPage as selectPropertyPage,
selectPageSize as selectPropertyPageSize,
useGetAllPropertiesQuery,
} from "~/features/properties/property.slice";
import {
ComponentType,
ExperienceConfigCreate,
Expand Down Expand Up @@ -109,6 +115,11 @@ export const PrivacyExperienceForm = ({
return `${name}${t.is_default ? " (Default)" : ""}`;
};

const propertyPage = useAppSelector(selectPropertyPage);
const propertyPageSize = useAppSelector(selectPropertyPageSize);
useGetAllPropertiesQuery({ page: propertyPage, size: propertyPageSize });
const allProperties = useAppSelector(selectAllProperties);

if (editingStyle) {
return (
<>
Expand Down Expand Up @@ -176,6 +187,19 @@ export const PrivacyExperienceForm = ({
/>
</Box>
</Collapse>
<ScrollableList
label="Associated properties"
addButtonLabel="Add property"
idField="id"
nameField="name"
allItems={allProperties.map((property) => ({
id: property.id,
name: property.name,
}))}
values={values.properties ?? []}
setValues={(newValues) => setFieldValue("properties", newValues)}
draggable
/>
<Divider />
<Heading fontSize="md" fontWeight="semibold">
Privacy notices
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,26 @@ export const PrivacyExperiencesTable = () => {
showHeaderMenu: true,
},
}),
columnHelper.accessor(
(row) => row.properties.map((property) => property.name),
{
id: "properties",
cell: (props) => (
<GroupCountBadgeCell
suffix="Properties"
value={props.getValue()}
{...props}
/>
),
header: (props) => (
<DefaultHeaderCell value="Properties" {...props} />
),
meta: {
displayText: "Properties",
showHeaderMenu: true,
},
}
),
columnHelper.accessor((row) => row.updated_at, {
id: "updated_at",
cell: (props) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const privacyExperienceConfigApi = baseApi.injectEndpoints({
body,
};
},
invalidatesTags: () => ["Privacy Experience Configs"],
invalidatesTags: () => ["Privacy Experience Configs", "Property"],
}),
limitedPatchExperienceConfig: build.mutation<
ExperienceConfigResponse,
Expand Down Expand Up @@ -114,7 +114,7 @@ const privacyExperienceConfigApi = baseApi.injectEndpoints({
url: `experience-config/`,
body: payload,
}),
invalidatesTags: () => ["Privacy Experience Configs"],
invalidatesTags: () => ["Privacy Experience Configs", "Property"],
}),
}),
});
Expand All @@ -137,6 +137,7 @@ export const { reducer } = privacyExperienceConfigSlice;

const selectPrivacyExperienceConfig = (state: RootState) =>
state.privacyExperienceConfig;

export const selectPage = createSelector(
selectPrivacyExperienceConfig,
(state) => state.page
Expand Down
55 changes: 40 additions & 15 deletions clients/admin-ui/src/features/properties/PropertiesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
DefaultHeaderCell,
FidesTableV2,
GlobalFilterV2,
GroupCountBadgeCell,
PaginationBar,
TableActionBar,
TableSkeletonLoader,
Expand All @@ -21,11 +22,12 @@ import _ from "lodash";
import { useRouter } from "next/router";
import { useEffect, useMemo, useState } from "react";

import { PROPERTIES_ROUTE } from "~/features/common/nav/v2/routes";
import Restrict, { useHasPermission } from "~/features/common/Restrict";
import { useGetHealthQuery } from "~/features/plus/plus.slice";
import { useGetPropertiesQuery } from "~/features/properties/property.slice";
import { Page_Property_, Property } from "~/types/api";
import { useGetAllPropertiesQuery } from "~/features/properties/property.slice";
import { Page_Property_, Property, ScopeRegistryEnum } from "~/types/api";

import { PROPERTIES_ROUTE } from "../common/nav/v2/routes";
import AddPropertyButton from "./AddPropertyButton";
import PropertyActions from "./PropertyActions";

Expand Down Expand Up @@ -54,17 +56,21 @@ const EmptyTableNotice = () => (
<Text fontSize="md" fontWeight="600">
No properties found.
</Text>
<Text fontSize="sm">
Click “Add property” to add your first property to Fides.
</Text>
<Restrict scopes={[ScopeRegistryEnum.PROPERTY_CREATE]}>
<Text fontSize="sm">
Click “Add property” to add your first property to Fides.
</Text>
<AddPropertyButton buttonLabel="Add property" buttonVariant="primary" />
</Restrict>
</VStack>
<AddPropertyButton buttonLabel="Add property" buttonVariant="primary" />
</VStack>
);

export const PropertiesTable = () => {
const { isLoading: isLoadingHealthCheck } = useGetHealthQuery();

const userCanUpdate = useHasPermission([ScopeRegistryEnum.PROPERTY_UPDATE]);

const {
PAGE_SIZES,
pageSize,
Expand All @@ -91,9 +97,9 @@ export const PropertiesTable = () => {
isFetching,
isLoading,
data: properties,
} = useGetPropertiesQuery({
pageIndex,
pageSize,
} = useGetAllPropertiesQuery({
page: pageIndex,
size: pageSize,
search: globalFilter,
});

Expand All @@ -119,6 +125,21 @@ export const PropertiesTable = () => {
cell: (props) => <DefaultCell value={_.capitalize(props.getValue())} />,
header: (props) => <DefaultHeaderCell value="Type" {...props} />,
}),
columnHelper.accessor((row) => row.experiences.map((exp) => exp.name), {
id: "experiences",
cell: (props) => (
<GroupCountBadgeCell
suffix="experiences"
value={props.getValue()}
{...props}
/>
),
header: (props) => <DefaultHeaderCell value="Experience" {...props} />,
meta: {
displayText: "Experience",
showHeaderMenu: true,
},
}),
columnHelper.display({
id: "actions",
header: "Actions",
Expand All @@ -141,7 +162,9 @@ export const PropertiesTable = () => {
});

const onRowClick = (property: Property) => {
router.push(`${PROPERTIES_ROUTE}/${property.key}`);
if (userCanUpdate) {
router.push(`${PROPERTIES_ROUTE}/${property.id}`);
}
};

if (isLoading || isLoadingHealthCheck) {
Expand All @@ -157,10 +180,12 @@ export const PropertiesTable = () => {
placeholder="Search property"
/>
<HStack alignItems="center" spacing={4}>
<AddPropertyButton
buttonLabel="Add property"
buttonVariant="outline"
/>
<Restrict scopes={[ScopeRegistryEnum.PROPERTY_CREATE]}>
<AddPropertyButton
buttonLabel="Add property"
buttonVariant="outline"
/>
</Restrict>
</HStack>
</TableActionBar>
<FidesTableV2
Expand Down
31 changes: 18 additions & 13 deletions clients/admin-ui/src/features/properties/PropertyActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Box, EditIcon, IconButton } from "@fidesui/react";
import { useRouter } from "next/router";
import React from "react";

import { Property } from "~/types/api";

import { PROPERTIES_ROUTE } from "../common/nav/v2/routes";
import NewJavaScriptTag from "../privacy-experience/NewJavaScriptTag";
import { PROPERTIES_ROUTE } from "~/features/common/nav/v2/routes";
import Restrict from "~/features/common/Restrict";
import NewJavaScriptTag from "~/features/privacy-experience/NewJavaScriptTag";
import { Property, ScopeRegistryEnum } from "~/types/api";

interface Props {
property: Property;
Expand All @@ -15,20 +15,25 @@ const PropertyActions = ({ property }: Props) => {
const router = useRouter();

const handleEdit = () => {
router.push(`${PROPERTIES_ROUTE}/${property.key}`);
router.push(`${PROPERTIES_ROUTE}/${property.id}`);
};

return (
<Box py={2}>
<NewJavaScriptTag property={property} />
<IconButton
aria-label="Edit property"
variant="outline"
size="xs"
marginRight="10px"
icon={<EditIcon />}
onClick={handleEdit}
/>
<Restrict scopes={[ScopeRegistryEnum.PROPERTY_UPDATE]}>
<IconButton
aria-label="Edit property"
variant="outline"
size="xs"
marginRight="10px"
icon={<EditIcon />}
onClick={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation();
handleEdit();
}}
/>
</Restrict>
</Box>
);
};
Expand Down
Loading
Loading