Skip to content

Commit

Permalink
Feature: Add the capability of setting "allow list" content policy (#376
Browse files Browse the repository at this point in the history
)

* Add permission for contentSettings

* Clear contentSettings.cookies when browser window is opened

* Add custom hook for allowed list

* Create state for and handle classes in body row

* Update TableProps and details component

* Add mock test data and test for bodyRow

* Add test for BodyRow

* Update useAllowedList hook to handle session storage

* Add test data for cookie table body

* Add method for adding domain to allow list

* Add new clors to tailwind

* Add condition before loopin through storage.allowList

* Refactor cdoe

* Refactor code

* Refactor code

* Add types

* Refactor code

* Refactor code

* Refactor code

* Use async/await instead of promise then

* Refactor code to move onClick function to a utility

* Update details section for allowed cookies

* Show green for an item that is not blocked and allow listed

* Show green border for allow listed items even if they are blocked

* Fix state update

* Capitalize R in blocked reason

* Refactor: Add the capability of setting "allow list" content policy (#422)

* Add new key in CookieTableData type

* Pass row context menu as prop and remove useAllowList hook

* Move useAllowedList logic into standalone functions

* Move conext menu into CookieListing and introduce states and callback for modal

* Remove selected row from table

* Stop propagation on click

* ref: Refactor the utils handling clicks, removal of domain, setting domain and parent domain

* perf: clean up unrequired calls

* chore: delete already moved files

* ref: Refactor useEffects

* fix: Update condition for getting domain in allow list

* ref: move row context menu ui and logic to separate component

* ref: move allowed list logic to a hook

* test: add tests for rowContextMenu

* fix: capitalize context menu options

* test: add tests for utils

* Add reloadCurrentTab to reload current tab

* Reload page on adding domain to allowed list

* Fix url pattern issue

* Fix styling for border left

* Update message

* Update text for context menu

* Allow cookies for domain with dot prefix

* Refactor code

* Fix tests

* Remove condition for fixing remove allow list issue

* Remove unused code for useHighlighting

* Fix parent domain double click issue

* Code improvements and refactoring

* Fix test case

* Add code improvements

* Fix test

* ref: use domains list as prop

* test: fix test

---------

Co-authored-by: Mayank Rana <58820001+mayan-000@users.noreply.github.com>
Co-authored-by: Mayank Rana <mayankranax1@gmail.com>
  • Loading branch information
3 people committed Jan 29, 2024
1 parent 5af12dd commit 85112cd
Show file tree
Hide file tree
Showing 35 changed files with 2,032 additions and 133 deletions.
1 change: 1 addition & 0 deletions packages/common/src/cookies.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export type CookieData = {
export type CookieTableData = CookieData & {
frameUrls?: string | string[];
highlighted?: boolean;
isDomainInAllowList?: boolean;
};

export type TechnologyData = {
Expand Down
19 changes: 17 additions & 2 deletions packages/design-system/src/components/cookieDetails/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface DetailsProps {

const Details = ({ selectedCookie }: DetailsProps) => {
const [showUrlDecoded, setShowUrlDecoded] = useState(false);

let blockedReasons = '';
let warningReasons = '';
//Adding a comment here for future reference, this was done because we are using 2 different APIs to gather cookie data and often the isBlocked gets toggled between true and false.
Expand Down Expand Up @@ -72,10 +73,24 @@ const Details = ({ selectedCookie }: DetailsProps) => {

return (
<div className="text-xs py-1 px-1.5">
{isCookieBlocked && blockedReasons && blockedReasons && (
{selectedCookie.isDomainInAllowList && (
<div className="mb-4">
<p className="font-bold text-raising-black dark:text-bright-gray mb-1">
Allow Listed
</p>
<p className="text-outer-space-crayola dark:text-bright-gray">
The cookie domain was added to the allow-list for this session,
however the browser may still block these cookies for various
reasons, such as invalid attributes. You can check the allowed
domains under chrome://settings/content/siteData.
</p>
</div>
)}

{isCookieBlocked && blockedReasons && (
<>
<p className="font-bold text-raising-black dark:text-bright-gray mb-1">
Blocked reason
Blocked Reason
</p>
<p
className="text-outer-space-crayola dark:text-bright-gray mb-3"
Expand Down
67 changes: 53 additions & 14 deletions packages/design-system/src/components/cookieTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
/**
* External dependencies.
*/
import React, { useCallback, useEffect, useMemo, useReducer } from 'react';
import React, {
forwardRef,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
useReducer,
} from 'react';
import { CookieTableData, getCookieKey } from '@ps-analysis-tool/common';

/**
Expand Down Expand Up @@ -48,20 +55,33 @@ interface CookieTableProps {
} | null
) => void;
extraInterfaceToTopBar?: React.ReactNode;
onRowContextMenu?: (
e: React.MouseEvent<HTMLDivElement>,
row: TableRow
) => void;
}

const CookieTable = ({
tableColumns,
tableFilters,
tableSearchKeys,
tablePersistentSettingsKey,
data: cookies,
showTopBar,
selectedFrame,
selectedFrameCookie,
setSelectedFrameCookie,
extraInterfaceToTopBar,
}: CookieTableProps) => {
const CookieTable = forwardRef<
{
removeSelectedRow: () => void;
},
CookieTableProps
>(function CookieTable(
{
tableColumns,
tableFilters,
tableSearchKeys,
tablePersistentSettingsKey,
data: cookies,
showTopBar,
selectedFrame,
selectedFrameCookie,
setSelectedFrameCookie,
extraInterfaceToTopBar,
onRowContextMenu,
}: CookieTableProps,
ref
) {
useEffect(() => {
if (selectedFrame && selectedFrameCookie) {
if (
Expand All @@ -84,6 +104,18 @@ const CookieTable = ({
[selectedFrame, setSelectedFrameCookie]
);

useImperativeHandle(
ref,
() => {
return {
removeSelectedRow: () => {
onRowClick(null);
},
};
},
[onRowClick]
);

const selectedKey = useMemo(
() => Object.values(selectedFrameCookie ?? {})[0],
[selectedFrameCookie]
Expand Down Expand Up @@ -119,9 +151,16 @@ const CookieTable = ({
}
onRowClick={onRowClick}
extraInterfaceToTopBar={extraInterfaceToTopBar}
onRowContextMenu={(
e: React.MouseEvent<HTMLDivElement>,
row: TableRow
) => {
onRowContextMenu?.(e, row);
onRowClick(row?.originalData);
}}
/>
</div>
);
};
});

export default CookieTable;
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ interface TableProps {
selectedKey: string | undefined | null;
getRowObjectKey: (row: TableRow) => string;
onRowClick: (row: TableData | null) => void;
onRowContextMenu?: (
e: React.MouseEvent<HTMLDivElement>,
row: TableRow
) => void;
showTopBar?: boolean;
hideFiltering?: boolean;
extraInterfaceToTopBar?: React.ReactNode;
Expand All @@ -45,6 +49,7 @@ const Table = ({
selectedKey,
getRowObjectKey,
onRowClick,
onRowContextMenu = () => undefined,
showTopBar = false,
hideFiltering = false,
extraInterfaceToTopBar,
Expand Down Expand Up @@ -150,6 +155,7 @@ const Table = ({
setIsRowFocused={setIsRowFocused}
selectedKey={selectedKey}
onRowClick={onRowClick}
onRowContextMenu={onRowContextMenu}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,78 +17,31 @@
/**
* External dependencies.
*/
import React, { useState, useCallback, useMemo } from 'react';
import { createPortal } from 'react-dom';
import React from 'react';

/**
* Internal dependencies.
*/
import type { InfoType, TableRow } from '../../useTable';
import { CookieTableData } from '@ps-analysis-tool/common';

interface BodyCellProps {
cell: React.JSX.Element | InfoType;
width: number;
isHighlighted?: boolean;
isRowFocused: boolean;
row: TableRow;
onRowClick: () => void;
onRowClick: (e: React.MouseEvent<HTMLDivElement>) => void;
}

const BodyCell = ({
onRowClick,
row,
cell,
width,
isRowFocused,
isHighlighted = false,
}: BodyCellProps) => {
const [contextMenuOpen, setContextMenuOpen] = useState(false);
const [columnPosition, setColumnPosition] = useState({
x: 0,
y: 0,
});

const handleRightClick = useCallback(
(e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
const x = e.clientX,
y = e.clientY;
onRowClick();
setColumnPosition({ x, y });
document.body.style.overflow = contextMenuOpen ? 'auto' : 'hidden';
setContextMenuOpen(!contextMenuOpen);
},
[contextMenuOpen, onRowClick]
);

const [domain, name] = useMemo(
() => [
(row?.originalData as CookieTableData)?.parsedCookie?.domain,
(row?.originalData as CookieTableData)?.parsedCookie?.name,
],
[row?.originalData]
);

const handleCopy = useCallback(() => {
try {
// Need to do this since chrome doesnt allow the clipboard access in extension.
const copyFrom = document.createElement('textarea');
copyFrom.textContent = `cookie-domain:${domain} cookie-name:${name}`;
document.body.appendChild(copyFrom);
copyFrom.select();
document.execCommand('copy');
copyFrom.blur();
document.body.removeChild(copyFrom);
setContextMenuOpen(false);
} catch (error) {
//Fail silently
}
}, [domain, name]);

return (
<div
tabIndex={0}
onContextMenu={handleRightClick}
onDoubleClick={(e) => {
const target = e.target as HTMLElement;
const range = new Range();
Expand All @@ -112,38 +65,6 @@ const BodyCell = ({
} cursor-default flex-1`}
>
{cell}
<>
{domain &&
name &&
contextMenuOpen &&
createPortal(
<div className="transition duration-100" data-testid="column-menu">
<div
className="absolute z-50 text-raisin-black dark:text-bright-gray rounded-md backdrop-blur-2xl w-screen max-w-[13rem] p-1.5 mr-2 divide-neutral-300 dark:divide-neutral-500 max-h-[78vh] overflow-auto bg-stone-200 dark:bg-neutral-700 shadow-3xl"
style={{
left:
'min( calc( 100vw - 15rem),' + columnPosition.x + 'px )',
top: columnPosition.y + 'px',
border: '0.5px solid rgba(0, 0, 0, 0.20)',
}}
>
<button
onClick={handleCopy}
className="w-full text-xs rounded px-1 py-[3px] flex items-center hover:bg-royal-blue hover:text-white cursor-default"
>
<span>Copy network filter string</span>
</button>
</div>

<div
data-testid="column-menu-overlay"
onClick={() => setContextMenuOpen(false)}
className="absolute w-screen h-screen z-10 top-0 left-0"
/>
</div>,
document.body
)}
</>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ interface BodyRowProps {
isRowFocused: boolean;
selectedKey: string | undefined | null;
getRowObjectKey: (row: TableRow) => string;
onRowClick: () => void;
onRowClick: (e: React.MouseEvent<HTMLDivElement>) => void;
onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>, index: number) => void;
onRowContextMenu?: (
e: React.MouseEvent<HTMLDivElement>,
row: TableRow
) => void;
}

// eslint-disable-next-line complexity
const BodyRow = ({
row,
columns,
Expand All @@ -47,15 +52,19 @@ const BodyRow = ({
isRowFocused,
onRowClick,
onKeyDown,
onRowContextMenu = () => undefined,
}: BodyRowProps) => {
const cookieKey = getRowObjectKey(row);
const isBlocked =
(row.originalData as CookieTableData)?.isBlocked ||
((row.originalData as CookieTableData)?.blockedReasons &&
(row.originalData as CookieTableData)?.blockedReasons?.length > 0);
(row.originalData as CookieTableData)?.blockedReasons?.length);
const isHighlighted = (row.originalData as CookieTableData)?.highlighted;
const isDomainInAllowList = (row.originalData as CookieTableData)
?.isDomainInAllowList;

const tableRowClassName = classNames(
'outline-0 flex divide-x divide-american-silver dark:divide-quartz',
'outline-0 flex divide-x divide-american-silver dark:divide-quartz relative',
isBlocked &&
(cookieKey !== selectedKey
? index % 2
Expand All @@ -64,8 +73,18 @@ const BodyRow = ({
: isRowFocused
? 'bg-gainsboro dark:bg-outer-space'
: 'bg-royal-blue text-white dark:bg-medium-persian-blue dark:text-chinese-silver'),
isDomainInAllowList &&
!isBlocked &&
(cookieKey !== selectedKey
? index % 2
? 'dark:bg-jungle-green-dark bg-leaf-green-dark'
: 'dark:bg-jungle-green-light bg-leaf-green-light'
: isRowFocused
? 'bg-gainsboro dark:bg-outer-space'
: 'bg-royal-blue text-white dark:bg-medium-persian-blue dark:text-chinese-silver'),
cookieKey !== selectedKey &&
!isBlocked &&
!isDomainInAllowList &&
(index % 2
? isHighlighted
? 'bg-dirty-pink'
Expand All @@ -75,6 +94,7 @@ const BodyRow = ({
: 'bg-white dark:bg-raisin-black'),
cookieKey === selectedKey &&
!isBlocked &&
!isDomainInAllowList &&
(isRowFocused
? isHighlighted
? 'bg-dirty-red'
Expand All @@ -90,8 +110,13 @@ const BodyRow = ({
className={tableRowClassName}
onClick={onRowClick}
onKeyDown={(e) => onKeyDown(e, index)}
onContextMenu={(e) => onRowContextMenu(e, row)}
data-testid="body-row"
>
{/* Vertical bar for allow-listed domain row at the left side */}
{isDomainInAllowList && (
<span className="absolute block top-0 bottom-0 left-0 border-l-2 border-emerald-600 dark:border-leaf-green-dark" />
)}
{columns.map(({ accessorKey, width }, idx) => (
<BodyCell
key={idx}
Expand Down
Loading

0 comments on commit 85112cd

Please sign in to comment.