feature(plugins/home): Remove DoNotTrack functionality
Signed-off-by: Renan Mendes Carvalho <aitherios@gmail.com> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
committed by
Camila Belo
parent
09a7f8f285
commit
a84cac67ca
@@ -14,14 +14,12 @@ import { CardSettings as CardSettings_2 } from '@backstage/plugin-home-react';
|
||||
import { ComponentParts as ComponentParts_2 } from '@backstage/plugin-home-react';
|
||||
import { ComponentRenderer as ComponentRenderer_2 } from '@backstage/plugin-home-react';
|
||||
import { createCardExtension as createCardExtension_2 } from '@backstage/plugin-home-react';
|
||||
import { Dispatch } from 'react';
|
||||
import { JSX as JSX_2 } from 'react';
|
||||
import { default as React_2 } from 'react';
|
||||
import { ReactElement } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
import { RendererProps as RendererProps_2 } from '@backstage/plugin-home-react';
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
import { SetStateAction } from 'react';
|
||||
|
||||
// @public
|
||||
export type Breakpoint = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
||||
@@ -100,13 +98,6 @@ export type CustomHomepageGridProps = {
|
||||
preventCollision?: boolean;
|
||||
};
|
||||
|
||||
// @public
|
||||
export const DoNotTrack: ({
|
||||
children,
|
||||
}: {
|
||||
children?: ReactNode;
|
||||
}) => JSX.Element;
|
||||
|
||||
// @public
|
||||
export const getVisitName: (document: Document) => () => string;
|
||||
|
||||
@@ -204,9 +195,6 @@ export type ToolkitContentProps = {
|
||||
tools: Tool[];
|
||||
};
|
||||
|
||||
// @public
|
||||
export const useVisitListener: () => VisitListenerContextValue;
|
||||
|
||||
// @public
|
||||
export type Visit = {
|
||||
id: string;
|
||||
@@ -242,15 +230,6 @@ export const VisitListener: ({
|
||||
visitName?: (({ pathname }: { pathname: string }) => string) | undefined;
|
||||
}) => JSX.Element;
|
||||
|
||||
// @public (undocumented)
|
||||
export const VisitListenerContext: React_2.Context<VisitListenerContextValue>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type VisitListenerContextValue = {
|
||||
doNotTrack: boolean;
|
||||
setDoNotTrack: Dispatch<SetStateAction<boolean>>;
|
||||
};
|
||||
|
||||
// @public
|
||||
export interface VisitsApi {
|
||||
listUserVisits(queryParams?: VisitsApiQueryParams): Promise<Visit[]>;
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
import React from 'react';
|
||||
import { TestApiProvider, renderInTestApp } from '@backstage/test-utils';
|
||||
import { Visit, visitsApiRef } from '../api';
|
||||
import { DoNotTrack, VisitListener, useVisitListener } from './VisitListener';
|
||||
import { VisitListener } from './VisitListener';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { act, renderHook } from '@testing-library/react-hooks';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
const visits: Array<Visit> = [
|
||||
{
|
||||
@@ -139,65 +137,3 @@ describe('<VisitListener/>', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('<DoNotTrack/>', () => {
|
||||
afterEach(jest.resetAllMocks);
|
||||
|
||||
it("doesn't register a visit", async () => {
|
||||
const requestAnimationFrameSpy = jest.spyOn(
|
||||
window,
|
||||
'requestAnimationFrame',
|
||||
);
|
||||
await renderInTestApp(
|
||||
<TestApiProvider apis={[[visitsApiRef, mockVisitsApi]]}>
|
||||
<VisitListener>
|
||||
<DoNotTrack />
|
||||
</VisitListener>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
await waitFor(() => expect(requestAnimationFrameSpy).toHaveBeenCalled());
|
||||
expect(mockVisitsApi.saveVisit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders its children', async () => {
|
||||
const requestAnimationFrameSpy = jest.spyOn(
|
||||
window,
|
||||
'requestAnimationFrame',
|
||||
);
|
||||
const { getByTestId } = await renderInTestApp(
|
||||
<TestApiProvider apis={[[visitsApiRef, mockVisitsApi]]}>
|
||||
<VisitListener>
|
||||
<DoNotTrack>
|
||||
<div data-testid="child">child</div>
|
||||
</DoNotTrack>
|
||||
</VisitListener>
|
||||
</TestApiProvider>,
|
||||
);
|
||||
await waitFor(() => expect(requestAnimationFrameSpy).toHaveBeenCalled());
|
||||
expect(getByTestId('child')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useVisitListener()', () => {
|
||||
it('returns the default context', () => {
|
||||
const { result } = renderHook(() => useVisitListener());
|
||||
expect(result.current.doNotTrack).toBeFalsy();
|
||||
expect(result.current.setDoNotTrack).toBeInstanceOf(Function);
|
||||
});
|
||||
|
||||
it('changes the doNotTrack flag', () => {
|
||||
const { result } = renderHook(() => useVisitListener(), {
|
||||
wrapper: ({ children }) => (
|
||||
<MemoryRouter>
|
||||
<TestApiProvider apis={[[visitsApiRef, mockVisitsApi]]}>
|
||||
<VisitListener>{children}</VisitListener>
|
||||
</TestApiProvider>
|
||||
</MemoryRouter>
|
||||
),
|
||||
});
|
||||
act(() => {
|
||||
result.current.setDoNotTrack(true);
|
||||
});
|
||||
expect(result.current.doNotTrack).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,15 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, {
|
||||
createContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useContext,
|
||||
Dispatch,
|
||||
SetStateAction,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
@@ -29,22 +21,6 @@ import { visitsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { stringifyEntityRef } from '@backstage/catalog-model';
|
||||
|
||||
/** @public */
|
||||
export type VisitListenerContextValue = {
|
||||
doNotTrack: boolean;
|
||||
setDoNotTrack: Dispatch<SetStateAction<boolean>>;
|
||||
};
|
||||
|
||||
const defaultVisitListenerContext: VisitListenerContextValue = {
|
||||
doNotTrack: false,
|
||||
setDoNotTrack: () => {},
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const VisitListenerContext = createContext<VisitListenerContextValue>(
|
||||
defaultVisitListenerContext,
|
||||
);
|
||||
|
||||
/**
|
||||
* This function returns an implementation of toEntityRef which is responsible
|
||||
* for receiving a pathname and maybe returning an entityRef compatible with the
|
||||
@@ -97,66 +73,24 @@ export const VisitListener = ({
|
||||
toEntityRef?: ({ pathname }: { pathname: string }) => string | undefined;
|
||||
visitName?: ({ pathname }: { pathname: string }) => string;
|
||||
}): JSX.Element => {
|
||||
const [doNotTrack, setDoNotTrack] = useState<boolean>(
|
||||
defaultVisitListenerContext.doNotTrack,
|
||||
);
|
||||
const visitsApi = useApi(visitsApiRef);
|
||||
const { pathname } = useLocation();
|
||||
const toEntityRefImpl = toEntityRef ?? getToEntityRef();
|
||||
const visitNameImpl = visitName ?? getVisitName(document);
|
||||
useEffect(() => {
|
||||
// Wait for the browser to finish with paint with the assumption react
|
||||
// has finished with dom reconciliation and the doNotTrack state update.
|
||||
// has finished with dom reconciliation.
|
||||
const requestId = requestAnimationFrame(() => {
|
||||
if (!doNotTrack)
|
||||
visitsApi.saveVisit({
|
||||
visit: {
|
||||
name: visitNameImpl({ pathname }),
|
||||
pathname,
|
||||
entityRef: toEntityRefImpl({ pathname }),
|
||||
},
|
||||
});
|
||||
visitsApi.saveVisit({
|
||||
visit: {
|
||||
name: visitNameImpl({ pathname }),
|
||||
pathname,
|
||||
entityRef: toEntityRefImpl({ pathname }),
|
||||
},
|
||||
});
|
||||
});
|
||||
return () => cancelAnimationFrame(requestId);
|
||||
}, [doNotTrack, visitsApi, pathname, toEntityRefImpl, visitNameImpl]);
|
||||
|
||||
return (
|
||||
<VisitListenerContext.Provider value={{ doNotTrack, setDoNotTrack }}>
|
||||
{children}
|
||||
</VisitListenerContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
* Hook used to access visit listener context. Is able to control if tracking
|
||||
* should be disabled.
|
||||
*/
|
||||
export const useVisitListener = () => {
|
||||
const value = useContext(VisitListenerContext);
|
||||
|
||||
if (value === undefined)
|
||||
throw new Error(
|
||||
'useVisitListener found an undefined context, <VisitListener/> could be missing',
|
||||
);
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
* Use this component to warn VisitListener to disable tracking.
|
||||
*/
|
||||
export const DoNotTrack = ({
|
||||
children,
|
||||
}: {
|
||||
children?: ReactNode;
|
||||
}): JSX.Element => {
|
||||
const { setDoNotTrack } = useVisitListener();
|
||||
useEffect(() => {
|
||||
setDoNotTrack(true);
|
||||
return () => setDoNotTrack(false);
|
||||
}, [setDoNotTrack]);
|
||||
}, [visitsApi, pathname, toEntityRefImpl, visitNameImpl]);
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user