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-2481 Update manage datasets pages #5191

Merged
merged 34 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d48482b
PROD-2481 Dataset table: add edit column
Aug 1, 2024
968258b
PROD-2481 Add edit drawer to dataset page
Aug 2, 2024
76b3fb8
PROD-2481 Adjust dataset drawer styling. Remove data categories input.
Aug 5, 2024
ffa9ab6
PROD-2481 Adjust dataset drawer styling.
Aug 5, 2024
2c9be2c
PROD-2481 Update add dataset buttons styling
Aug 5, 2024
bd86904
PROD-2481 WIP
Aug 9, 2024
d15b840
PROD-2481 WIP
Aug 13, 2024
a2a9675
PROD-2481 WIP
Aug 13, 2024
bc6530f
Merge branch 'main' of github.com:ethyca/fides into PROD-2481-Update-…
Aug 13, 2024
d55bb93
PROD-2481 WIP
Aug 13, 2024
1a9890b
PROD-2481 WIP
Aug 14, 2024
21a5b57
PROD-2481 Add dataset breadcrumbs and icons
Aug 14, 2024
8538347
PROD-2481 Dataset Header styling
Aug 14, 2024
9f014ce
PROD_2481 Client side search
Aug 14, 2024
6cb04f4
PROD-2481 Fix bug with closing tray
Aug 14, 2024
c0df9d4
PROD-2481 Remove unused files after refactor
Aug 14, 2024
92832e8
Merge branch 'main' of github.com:ethyca/fides into PROD-2481-Update-…
Aug 14, 2024
d081341
PROD-2481 Fix lint issues
Aug 14, 2024
32b67cf
PROD-2481 Update changelog
Aug 14, 2024
0b21ec2
PROD-2481 fix build issuer
Aug 14, 2024
6e8301e
PROD-2481 Update tests
Aug 14, 2024
4937471
PROD-2481 Fix not being able to add data categories after removing al…
Aug 14, 2024
3e16c05
Merge branch 'main' of github.com:ethyca/fides into PROD-2481-Update-…
Aug 14, 2024
99bbd6c
Fixed datset breadcrumb icons size
Aug 14, 2024
54fb01f
Merge branch 'main' of github.com:ethyca/fides into PROD-2481-Update-…
Aug 14, 2024
de1e130
PROD-2481 Adjust D&D title and breadcrumbs for consistency. Remove du…
Aug 14, 2024
0551240
fix findResourceType
jpople Aug 14, 2024
6c08541
Eslint fix
Aug 14, 2024
752ed61
PROD-2481 Update tests
Aug 14, 2024
0ad2e9b
PROD-2481 Update tests
Aug 14, 2024
fbaa7ab
PROD-2481 Fix build
Aug 14, 2024
77e461b
PROD-2481 Fix build
Aug 14, 2024
88e1f39
PROD-2481 Delete test for Dataset classification that were skipped al…
Aug 14, 2024
48aea5d
Fix tests
Aug 14, 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
53 changes: 40 additions & 13 deletions clients/admin-ui/src/features/common/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink } from "fidesui";
import {
Box,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the breadcrumbs component. Added support for icons, expanded Link to be able to receive query params, added prop optionally be able to override some styles. Remove isOpaque props since it was too specific and it won't be used anymore. Removed onClick since it wasn't working nor being used.

Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbProps as ChakraBreadcrumbProps,
HTMLChakraProps,
} from "fidesui";
import { Url } from "next/dist/shared/lib/router/router";
import NextLink from "next/link";

export interface BreadcrumbsProps {
export interface BreadcrumbsProps extends ChakraBreadcrumbProps {
breadcrumbs: {
title: string;
link?: string;
link?: Url; // Next.js link url. It can be a string or an URL object (accepts query params)
onClick?: () => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know this existed, neat.

isOpaque?: boolean;
icon?: React.ReactNode;
}[];
fontSize?: string;
fontWeight?: string;
separator?: string;
lastItemStyles?: HTMLChakraProps<"li">;
normalItemStyles?: HTMLChakraProps<"li">;
}

/**
Expand All @@ -16,25 +29,39 @@ export interface BreadcrumbsProps {
* @param breadcrumbs - array of breadcrumbs
* @param breadcrumbs.title - title of the breadcrumb
* @param breadcrumbs.link - (optional) link to the page
* @param breadcrumbs.onClick - (optional) function to call when the breadcrumb is clicked
* @param breadcrumbs.isOpaque - (optional) if true, the breadcrumb will be black, otherwise gray
* @param breadcrumbs.icon - (optional) icon to show before the title
*/
const Breadcrumbs = ({ breadcrumbs }: BreadcrumbsProps) => (
const Breadcrumbs = ({
breadcrumbs,
fontSize = "2xl",
fontWeight = "semibold",
separator = "->",
lastItemStyles = {
color: "black",
},
normalItemStyles = {
color: "gray.500",
},
...otherChakraBreadcrumbProps
}: BreadcrumbsProps) => (
<Breadcrumb
separator="->"
fontSize="2xl"
fontWeight="semibold"
separator={separator}
fontSize={fontSize}
fontWeight={fontWeight}
data-testid="breadcrumbs"
{...otherChakraBreadcrumbProps}
>
{breadcrumbs.map((breadcumbItem, index) => {
const isLast = index + 1 === breadcrumbs.length;
const hasLink = !!breadcumbItem.link || !!breadcumbItem.onClick;

return (
<BreadcrumbItem
color={isLast || breadcumbItem.isOpaque ? "black" : "gray.500"}
{...normalItemStyles}
{...(isLast ? lastItemStyles : {})}
key={breadcumbItem.title}
>
{hasLink ? (
{breadcumbItem?.icon && <Box mr={2}>{breadcumbItem.icon}</Box>}
{breadcumbItem.link ? (
<BreadcrumbLink
as={NextLink}
href={breadcumbItem.link}
Expand Down
55 changes: 36 additions & 19 deletions clients/admin-ui/src/features/common/EditDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated edit drawer component with some new styling.

Box,
Button,
CloseSolidIcon,
CloseIcon,
Drawer,
DrawerBody,
DrawerContent,
Expand All @@ -10,10 +10,11 @@ import {
DrawerOverlay,
IconButton,
Text,
TrashCanSolidIcon,
} from "fidesui";
import { ReactNode } from "react";

import { TrashCanOutlineIcon } from "~/features/common/Icon/TrashCanOutlineIcon";

interface Props {
header?: ReactNode;
description?: string;
Expand All @@ -30,13 +31,16 @@ export const EditDrawerHeader = ({
title: string;
onDelete?: () => void;
}) => (
<DrawerHeader py={2} display="flex" alignItems="center">
<Text mr="2">{title}</Text>
<DrawerHeader py={0} display="flex" alignItems="flex-start">
<Text mr="2" color="gray.700" fontSize="lg" lineHeight={1.8}>
{title}
</Text>
{onDelete ? (
<IconButton
variant="outline"
aria-label="delete"
icon={<TrashCanSolidIcon />}
size="xs"
icon={<TrashCanOutlineIcon fontSize="small" />}
size="sm"
onClick={onDelete}
data-testid="delete-btn"
/>
Expand All @@ -56,7 +60,7 @@ export const EditDrawerFooter = ({
formId?: string;
isSaving?: boolean;
} & Pick<Props, "onClose">) => (
<DrawerFooter justifyContent="flex-start">
<DrawerFooter justifyContent="space-between">
<Button onClick={onClose} mr={2} size="sm" variant="outline">
Cancel
</Button>
Expand All @@ -81,22 +85,35 @@ const EditDrawer = ({
children,
footer,
}: Props) => (
<Drawer placement="right" isOpen={isOpen} onClose={onClose} size="lg">
<Drawer placement="right" isOpen={isOpen} onClose={onClose} size="md">
<DrawerOverlay />
<DrawerContent data-testid="edit-drawer-content" py={2}>
<Box display="flex" justifyContent="flex-end" mr={2}>
<Button
variant="ghost"
onClick={onClose}
data-testid="close-drawer-btn"
>
<CloseSolidIcon width="17px" />
</Button>
<Box
display="flex"
justifyContent="space-between"
alignItems="top"
mr={2}
py={2}
gap={2}
>
<Box flex={1} minH={8}>
{header}
</Box>
<Box display="flex" justifyContent="flex-end" mr={2}>
<IconButton
aria-label="Close editor"
variant="outline"
onClick={onClose}
data-testid="close-drawer-btn"
size="sm"
icon={<CloseIcon fontSize="smaller" />}
/>
</Box>
</Box>
{header}
<DrawerBody>

<DrawerBody pt={1}>
{description ? (
<Text fontSize="sm" mb={4}>
<Text fontSize="sm" mb={4} color="gray.600">
{description}
</Text>
) : null}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createIcon } from "fidesui";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied the icons from the D&D branch but I placed them in a more generic folder so we can use them for both features.


export const DatabaseIcon = createIcon({
displayName: "DatabaseIcon",
viewBox: "0 0 12 12",
path: (
<path
fill="currentColor"
d="M6 12C4.32222 12 2.90278 11.7417 1.74167 11.225C0.580556 10.7083 0 10.0778 0 9.33333V2.66667C0 1.93333 0.586111 1.30556 1.75833 0.783333C2.93056 0.261111 4.34444 0 6 0C7.65556 0 9.06944 0.261111 10.2417 0.783333C11.4139 1.30556 12 1.93333 12 2.66667V9.33333C12 10.0778 11.4194 10.7083 10.2583 11.225C9.09722 11.7417 7.67778 12 6 12ZM6 4.01667C6.98889 4.01667 7.98333 3.875 8.98333 3.59167C9.98333 3.30833 10.5444 3.00556 10.6667 2.68333C10.5444 2.36111 9.98611 2.05556 8.99167 1.76667C7.99722 1.47778 7 1.33333 6 1.33333C4.98889 1.33333 3.99722 1.475 3.025 1.75833C2.05278 2.04167 1.48889 2.35 1.33333 2.68333C1.48889 3.01667 2.05278 3.32222 3.025 3.6C3.99722 3.87778 4.98889 4.01667 6 4.01667ZM6 7.33333C6.46667 7.33333 6.91667 7.31111 7.35 7.26667C7.78333 7.22222 8.19722 7.15833 8.59167 7.075C8.98611 6.99167 9.35833 6.88889 9.70833 6.76667C10.0583 6.64444 10.3778 6.50556 10.6667 6.35V4.35C10.3778 4.50556 10.0583 4.64444 9.70833 4.76667C9.35833 4.88889 8.98611 4.99167 8.59167 5.075C8.19722 5.15833 7.78333 5.22222 7.35 5.26667C6.91667 5.31111 6.46667 5.33333 6 5.33333C5.53333 5.33333 5.07778 5.31111 4.63333 5.26667C4.18889 5.22222 3.76944 5.15833 3.375 5.075C2.98056 4.99167 2.61111 4.88889 2.26667 4.76667C1.92222 4.64444 1.61111 4.50556 1.33333 4.35V6.35C1.61111 6.50556 1.92222 6.64444 2.26667 6.76667C2.61111 6.88889 2.98056 6.99167 3.375 7.075C3.76944 7.15833 4.18889 7.22222 4.63333 7.26667C5.07778 7.31111 5.53333 7.33333 6 7.33333ZM6 10.6667C6.51111 10.6667 7.03056 10.6278 7.55833 10.55C8.08611 10.4722 8.57222 10.3694 9.01667 10.2417C9.46111 10.1139 9.83333 9.96945 10.1333 9.80833C10.4333 9.64722 10.6111 9.48333 10.6667 9.31667V7.68333C10.3778 7.83889 10.0583 7.97778 9.70833 8.1C9.35833 8.22222 8.98611 8.325 8.59167 8.40833C8.19722 8.49167 7.78333 8.55556 7.35 8.6C6.91667 8.64444 6.46667 8.66667 6 8.66667C5.53333 8.66667 5.07778 8.64444 4.63333 8.6C4.18889 8.55556 3.76944 8.49167 3.375 8.40833C2.98056 8.325 2.61111 8.22222 2.26667 8.1C1.92222 7.97778 1.61111 7.83889 1.33333 7.68333V9.33333C1.38889 9.5 1.56389 9.66111 1.85833 9.81667C2.15278 9.97222 2.52222 10.1139 2.96667 10.2417C3.41111 10.3694 3.9 10.4722 4.43333 10.55C4.96667 10.6278 5.48889 10.6667 6 10.6667Z"
/>
),
});
12 changes: 12 additions & 0 deletions clients/admin-ui/src/features/common/Icon/database/DatasetIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createIcon } from "fidesui";

export const DatasetIcon = createIcon({
displayName: "DatasetIcon",
viewBox: "0 0 16 16",
path: (
<path
fill="currentColor"
d="M2 14V2H14V14H2ZM3.33333 12.6667H12.6667V3.33333H3.33333V12.6667ZM4.66667 7.33333H7.33333V4.66667H4.66667V7.33333ZM8.66667 7.33333H11.3333V4.66667H8.66667V7.33333ZM4.66667 11.3333H7.33333V8.66667H4.66667V11.3333ZM8.66667 11.3333H11.3333V8.66667H8.66667V11.3333Z"
/>
),
});
12 changes: 12 additions & 0 deletions clients/admin-ui/src/features/common/Icon/database/FieldIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createIcon } from "fidesui";

export const FieldIcon = createIcon({
displayName: "FieldIcon",
viewBox: "0 0 16 16",
path: (
<path
d="M12.6667 12.6667V10.6667H3.33333V12.6667H12.6667ZM12.6667 9.33333V6.66667H3.33333V9.33333H12.6667ZM12.6667 5.33333V3.33333H3.33333V5.33333H12.6667ZM3.33333 14C2.96667 14 2.65278 13.8694 2.39167 13.6083C2.13056 13.3472 2 13.0333 2 12.6667V3.33333C2 2.96667 2.13056 2.65278 2.39167 2.39167C2.65278 2.13056 2.96667 2 3.33333 2H12.6667C13.0333 2 13.3472 2.13056 13.6083 2.39167C13.8694 2.65278 14 2.96667 14 3.33333V12.6667C14 13.0333 13.8694 13.3472 13.6083 13.6083C13.3472 13.8694 13.0333 14 12.6667 14H3.33333Z"
fill="currentColor"
/>
),
});
12 changes: 12 additions & 0 deletions clients/admin-ui/src/features/common/Icon/database/TableIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createIcon } from "fidesui";

export const TableIcon = createIcon({
displayName: "TableIcon",
viewBox: "0 0 16 16",
path: (
<path
fill="currentColor"
d="M2 14V2H14V14H2ZM3.33333 6H12.6667V3.33333H3.33333V6ZM6.88333 9.33333H9.11667V7.33333H6.88333V9.33333ZM6.88333 12.6667H9.11667V10.6667H6.88333V12.6667ZM3.33333 9.33333H5.55V7.33333H3.33333V9.33333ZM10.45 9.33333H12.6667V7.33333H10.45V9.33333ZM3.33333 12.6667H5.55V10.6667H3.33333V12.6667ZM10.45 12.6667H12.6667V10.6667H10.45V12.6667Z"
/>
),
});
26 changes: 17 additions & 9 deletions clients/admin-ui/src/features/common/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, BoxProps } from "fidesui";
import { Box, BoxProps, Flex } from "fidesui";
import { isArray } from "lodash";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added rightContent prop to PageHeader. Useful in new designs for buttons on the right of the page header.

import { isValidElement, ReactElement } from "react";

Expand All @@ -7,6 +7,7 @@ import Breadcrumbs, { BreadcrumbsProps } from "~/features/common/Breadcrumbs";
interface PageHeaderProps extends BoxProps {
breadcrumbs: BreadcrumbsProps["breadcrumbs"] | ReactElement | false;
isSticky?: boolean;
rightContent?: ReactElement;
}

/**
Expand All @@ -16,12 +17,14 @@ interface PageHeaderProps extends BoxProps {
* Can be an array of breadcrumb items (more information on Breadcrumbs component), a React element
* if you want to render something else, or false to not show any breadcrumbs.
* @param isSticky - Whether the page header should stick to the top of the page while scrolling. Defaults to true.
* @param children - Additional content to display in the header.
* @param children - Additional content to display in the header at the bottom.
* @param rightContent - Additional content to display in the header on the right side. Usually for displaying buttons.
*/
const PageHeader = ({
breadcrumbs,
isSticky = true,
children,
rightContent,
...otherProps
}: PageHeaderProps): JSX.Element => (
<Box
Expand All @@ -30,14 +33,19 @@ const PageHeader = ({
{...(isSticky ? { position: "sticky", top: 0, left: 0, zIndex: 10 } : {})}
{...otherProps}
>
{/* If breadcrumbs is an array, render the Breadcrumbs component. */}
{isArray(breadcrumbs) && (
<Box marginBottom={children ? 4 : 0}>
<Breadcrumbs breadcrumbs={breadcrumbs} />
<Flex alignItems="flex-start">
<Box flex={1}>
{/* If breadcrumbs is an array, render the Breadcrumbs component. */}
{isArray(breadcrumbs) && (
<Box marginBottom={children ? 4 : 0}>
<Breadcrumbs breadcrumbs={breadcrumbs} />
</Box>
)}
{/* If breadcrumbs is a React element, render it. */}
{isValidElement(breadcrumbs) && breadcrumbs}
</Box>
)}
{/* If breadcrumbs is a React element, render it. */}
{isValidElement(breadcrumbs) && breadcrumbs}
{rightContent && <Box>{rightContent}</Box>}
</Flex>

{children}
</Box>
Expand Down
103 changes: 103 additions & 0 deletions clients/admin-ui/src/features/common/TaxonomiesPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a more generic version of the TaxonomyDisplayAndEdit component so I could use it in the dataset page. The idea is that later we can re-use it for D&D or for the TaxonomyDisplayAndEdit component.

Badge,
Box,
CloseIcon,
EditIcon,
IconButton,
SmallAddIcon,
Wrap,
} from "fidesui";
import { useCallback, useState } from "react";
import TaxonomySelectDropdown from "~/features/common/dropdown/TaxonomySelectDropdown";
import { useOutsideClick } from "~/features/common/hooks";

import useTaxonomies from "./hooks/useTaxonomies";

interface TaxonomiesPickerProps {
selectedTaxonomies: string[];
onAddTaxonomy: (taxonomy: string) => void;
onRemoveTaxonomy: (taxonomy: string) => void;
}

const TaxonomiesPicker = ({
selectedTaxonomies,
onAddTaxonomy,
onRemoveTaxonomy,
}: TaxonomiesPickerProps) => {
const [isAdding, setIsAdding] = useState(false);
const { getDataCategoryDisplayName } = useTaxonomies();

const handleClickOutside = useCallback(() => {
setIsAdding(false);
}, []);

const { ref } = useOutsideClick(handleClickOutside);

if (!selectedTaxonomies?.length) {
return <Badge textTransform="none">None</Badge>;
}

return (
<Wrap
py={2}
alignItems="center"
position="relative"
width="100%"
gap={2}
overflowX="auto"
ref={ref}
>
{selectedTaxonomies.map((category) => (
<Badge
fontWeight="normal"
textTransform="none"
data-testid={`classification-${category}`}
px={1.5}
key={category}
>
{getDataCategoryDisplayName(category)}
<IconButton
onClick={() => onRemoveTaxonomy(category)}
icon={<CloseIcon boxSize={2} />}
size="2xs"
mt={-0.5}
ml={2}
aria-label="Remove category"
/>
</Badge>
))}
<IconButton
w="20px"
h="20px"
minW="20px"
borderRadius="sm"
icon={<SmallAddIcon />}
onClick={() => setIsAdding(true)}
data-testid="add-category-btn"
aria-label="Add category"
/>

{isAdding && (
<Box
className="select-wrapper"
position="absolute"
zIndex={10}
top="0"
left="0"
width="100%"
height="max"
bgColor="#fff"
>
<TaxonomySelectDropdown
onChange={(o) => {
setIsAdding(false);
onAddTaxonomy(o.value);
}}
menuIsOpen
/>
</Box>
)}
</Wrap>
);
};
export default TaxonomiesPicker;
Loading
Loading