frontend: rename detection page to trackers, drop SCRIPT/IFRAME branches

- Rename configuration/detection/ to configuration/trackers/.
- Rename files: CookieBannerDetectionPage* → CookieBannerTrackersPage*,
  DetectionPatternRow* → TrackerPatternRow*.
- Update GraphQL operation/fragment names and connection keys.
- Update route path "detection" → "trackers" and tab label.
- Remove SCRIPT/IFRAME cases from trackerTypeLabel() switch.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-05-08 19:13:45 +04:00
parent 36dbe47192
commit 030fdf4be3
8 changed files with 67 additions and 60 deletions

View File

@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
import { ClipboardTextIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
import { ClipboardTextIcon, CodeIcon, MagnifyingGlassIcon } from "@phosphor-icons/react";
import { formatError, type GraphQLError } from "@probo/helpers";
import { useTranslate } from "@probo/i18n";
import {
@@ -247,9 +247,13 @@ export default function CookieBannerConfigLayout({ queryRef }: CookieBannerConfi
<IconGlobe size={20} />
{__("Translations")}
</TabLink>
<TabLink to={`/organizations/${organizationId}/cookie-banners/${cookieBannerId}/detection`}>
<TabLink to={`/organizations/${organizationId}/cookie-banners/${cookieBannerId}/trackers`}>
<MagnifyingGlassIcon size={20} />
{__("Detection")}
{__("Trackers")}
</TabLink>
<TabLink to={`/organizations/${organizationId}/cookie-banners/${cookieBannerId}/resources`}>
<CodeIcon size={20} />
{__("Resources")}
</TabLink>
<TabLink to={`/organizations/${organizationId}/cookie-banners/${cookieBannerId}/consent-records`}>
<ClipboardTextIcon size={20} />

View File

@@ -31,31 +31,31 @@ import {
usePreloadedQuery,
} from "react-relay";
import type { CookieBannerDetectionPageFragment$key } from "#/__generated__/core/CookieBannerDetectionPageFragment.graphql";
import type { CookieBannerDetectionPageQuery } from "#/__generated__/core/CookieBannerDetectionPageQuery.graphql";
import type { CookieBannerTrackersPageFragment$key } from "#/__generated__/core/CookieBannerTrackersPageFragment.graphql";
import type { CookieBannerTrackersPageQuery } from "#/__generated__/core/CookieBannerTrackersPageQuery.graphql";
import type {
CookieBannerDetectionPageRefetchQuery,
CookieBannerTrackersPageRefetchQuery,
CookieSource,
TrackerPatternOrderField,
} from "#/__generated__/core/CookieBannerDetectionPageRefetchQuery.graphql";
} from "#/__generated__/core/CookieBannerTrackersPageRefetchQuery.graphql";
import { SortableTable, SortableTh } from "#/components/SortableTable";
import { DetectionPatternRow } from "./_components/DetectionPatternRow";
import { TrackerPatternRow } from "./_components/TrackerPatternRow";
export const cookieBannerDetectionPageQuery = graphql`
query CookieBannerDetectionPageQuery($cookieBannerId: ID!) {
export const cookieBannerTrackersPageQuery = graphql`
query CookieBannerTrackersPageQuery($cookieBannerId: ID!) {
node(id: $cookieBannerId) @required(action: THROW) {
__typename
... on CookieBanner {
...CookieBannerDetectionPageFragment
...CookieBannerTrackersPageFragment
}
}
}
`;
const detectionFragment = graphql`
fragment CookieBannerDetectionPageFragment on CookieBanner
@refetchable(queryName: "CookieBannerDetectionPageRefetchQuery")
const trackersFragment = graphql`
fragment CookieBannerTrackersPageFragment on CookieBanner
@refetchable(queryName: "CookieBannerTrackersPageRefetchQuery")
@argumentDefinitions(
first: { type: "Int", defaultValue: 50 }
order: { type: "TrackerPatternOrder", defaultValue: { field: NAME, direction: ASC } }
@@ -74,7 +74,7 @@ const detectionFragment = graphql`
filter: { query: $query, source: $source }
)
@connection(
key: "CookieBannerDetectionPage_uncategorisedTrackerPatterns"
key: "CookieBannerTrackersPage_uncategorisedTrackerPatterns"
filters: ["filter", "orderBy"]
)
@required(action: THROW) {
@@ -82,22 +82,22 @@ const detectionFragment = graphql`
edges {
node {
id
...DetectionPatternRowFragment
...TrackerPatternRowFragment
}
}
}
}
`;
interface CookieBannerDetectionPageProps {
queryRef: PreloadedQuery<CookieBannerDetectionPageQuery>;
interface CookieBannerTrackersPageProps {
queryRef: PreloadedQuery<CookieBannerTrackersPageQuery>;
}
export default function CookieBannerDetectionPage({
export default function CookieBannerTrackersPage({
queryRef,
}: CookieBannerDetectionPageProps) {
}: CookieBannerTrackersPageProps) {
const { __ } = useTranslate();
const data = usePreloadedQuery(cookieBannerDetectionPageQuery, queryRef);
const data = usePreloadedQuery(cookieBannerTrackersPageQuery, queryRef);
if (data.node.__typename !== "CookieBanner") {
throw new Error("invalid type for node");
@@ -108,9 +108,9 @@ export default function CookieBannerDetectionPage({
const [sourceFilter, setSourceFilter] = useState<CookieSource | null>(null);
const { data: fragmentData, ...pagination } = usePaginationFragment<
CookieBannerDetectionPageRefetchQuery,
CookieBannerDetectionPageFragment$key
>(detectionFragment, data.node);
CookieBannerTrackersPageRefetchQuery,
CookieBannerTrackersPageFragment$key
>(trackersFragment, data.node);
const connectionId = fragmentData.uncategorisedTrackerPatterns.__id;
const patterns = fragmentData.uncategorisedTrackerPatterns.edges.map(edge => edge.node) ?? [];
@@ -187,7 +187,7 @@ export default function CookieBannerDetectionPage({
</Thead>
<Tbody>
{patterns.map(pattern => (
<DetectionPatternRow
<TrackerPatternRow
key={pattern.id}
patternKey={pattern}
connectionId={connectionId}

View File

@@ -16,19 +16,19 @@ import { Suspense, useEffect } from "react";
import { useQueryLoader } from "react-relay";
import { useParams } from "react-router";
import type { CookieBannerDetectionPageQuery } from "#/__generated__/core/CookieBannerDetectionPageQuery.graphql";
import type { CookieBannerTrackersPageQuery } from "#/__generated__/core/CookieBannerTrackersPageQuery.graphql";
import CookieBannerDetectionPage, { cookieBannerDetectionPageQuery } from "./CookieBannerDetectionPage";
import { CookieBannerDetectionPageSkeleton } from "./CookieBannerDetectionPageSkeleton";
import CookieBannerTrackersPage, { cookieBannerTrackersPageQuery } from "./CookieBannerTrackersPage";
import { CookieBannerTrackersPageSkeleton } from "./CookieBannerTrackersPageSkeleton";
export default function CookieBannerDetectionPageLoader() {
export default function CookieBannerTrackersPageLoader() {
const { cookieBannerId } = useParams<{ cookieBannerId: string }>();
if (typeof cookieBannerId !== "string") {
throw new Error("Missing cookieBannerId parameter");
}
const [queryRef, loadQuery] = useQueryLoader<CookieBannerDetectionPageQuery>(
cookieBannerDetectionPageQuery,
const [queryRef, loadQuery] = useQueryLoader<CookieBannerTrackersPageQuery>(
cookieBannerTrackersPageQuery,
);
useEffect(() => {
@@ -36,12 +36,12 @@ export default function CookieBannerDetectionPageLoader() {
}, [loadQuery, cookieBannerId]);
if (!queryRef) {
return <CookieBannerDetectionPageSkeleton />;
return <CookieBannerTrackersPageSkeleton />;
}
return (
<Suspense fallback={<CookieBannerDetectionPageSkeleton />}>
<CookieBannerDetectionPage queryRef={queryRef} />
<Suspense fallback={<CookieBannerTrackersPageSkeleton />}>
<CookieBannerTrackersPage queryRef={queryRef} />
</Suspense>
);
}

View File

@@ -12,7 +12,7 @@
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
export function CookieBannerDetectionPageSkeleton() {
export function CookieBannerTrackersPageSkeleton() {
return (
<div className="space-y-4 animate-pulse">
<div className="flex items-center gap-4">

View File

@@ -31,20 +31,20 @@ import { graphql, useFragment, useMutation, useQueryLoader } from "react-relay";
import { useParams } from "react-router";
import { ConnectionHandler } from "relay-runtime";
import type { DetectionPatternRowDeleteMutation } from "#/__generated__/core/DetectionPatternRowDeleteMutation.graphql";
import type { DetectionPatternRowFragment$key } from "#/__generated__/core/DetectionPatternRowFragment.graphql";
import type { DetectionPatternRowMoveMutation } from "#/__generated__/core/DetectionPatternRowMoveMutation.graphql";
import type { DetectionPatternRowUpdateMutation } from "#/__generated__/core/DetectionPatternRowUpdateMutation.graphql";
import type { TrackerPatternRowDeleteMutation } from "#/__generated__/core/TrackerPatternRowDeleteMutation.graphql";
import type { TrackerPatternRowFragment$key } from "#/__generated__/core/TrackerPatternRowFragment.graphql";
import type { TrackerPatternRowMoveMutation } from "#/__generated__/core/TrackerPatternRowMoveMutation.graphql";
import type { TrackerPatternRowUpdateMutation } from "#/__generated__/core/TrackerPatternRowUpdateMutation.graphql";
import type { MoveToCategoryDropdownQuery } from "#/__generated__/core/MoveToCategoryDropdownQuery.graphql";
import { DetectionPatternRowEdit } from "./DetectionPatternRowEdit";
import { TrackerPatternRowEdit } from "./TrackerPatternRowEdit";
import {
MoveToCategoryDropdown,
moveToCategoryDropdownQuery,
} from "./MoveToCategoryDropdown";
const detectionPatternFragment = graphql`
fragment DetectionPatternRowFragment on TrackerPattern {
const trackerPatternFragment = graphql`
fragment TrackerPatternRowFragment on TrackerPattern {
id
trackerType
displayName
@@ -58,7 +58,7 @@ const detectionPatternFragment = graphql`
`;
const deletePatternMutation = graphql`
mutation DetectionPatternRowDeleteMutation(
mutation TrackerPatternRowDeleteMutation(
$input: DeleteTrackerPatternInput!
$connections: [ID!]!
) {
@@ -77,7 +77,7 @@ const deletePatternMutation = graphql`
`;
const movePatternMutation = graphql`
mutation DetectionPatternRowMoveMutation(
mutation TrackerPatternRowMoveMutation(
$input: MoveTrackerPatternToCategoryInput!
) {
moveTrackerPatternToCategory(input: $input) {
@@ -100,7 +100,7 @@ const movePatternMutation = graphql`
`;
const updatePatternMutation = graphql`
mutation DetectionPatternRowUpdateMutation(
mutation TrackerPatternRowUpdateMutation(
$input: UpdateTrackerPatternInput!
) {
updateTrackerPattern(input: $input) {
@@ -130,23 +130,21 @@ function trackerTypeLabel(type: string, __: (s: string) => string): string {
case "LOCAL_STORAGE": return __("localStorage");
case "SESSION_STORAGE": return __("sessionStorage");
case "INDEXED_DB": return __("IndexedDB");
case "SCRIPT": return __("Script");
case "IFRAME": return __("Iframe");
default: return type;
}
}
interface DetectionPatternRowProps {
patternKey: DetectionPatternRowFragment$key;
interface TrackerPatternRowProps {
patternKey: TrackerPatternRowFragment$key;
connectionId: string;
}
export function DetectionPatternRow({ patternKey, connectionId }: DetectionPatternRowProps) {
export function TrackerPatternRow({ patternKey, connectionId }: TrackerPatternRowProps) {
const { __ } = useTranslate();
const { toast } = useToast();
const confirm = useConfirm();
const { cookieBannerId } = useParams<{ cookieBannerId: string }>();
const pattern = useFragment(detectionPatternFragment, patternKey);
const pattern = useFragment(trackerPatternFragment, patternKey);
const [isEditing, setIsEditing] = useState(false);
const [categoryQueryRef, loadCategoryQuery]
@@ -162,11 +160,11 @@ export function DetectionPatternRow({ patternKey, connectionId }: DetectionPatte
);
const [deletePattern]
= useMutation<DetectionPatternRowDeleteMutation>(deletePatternMutation);
= useMutation<TrackerPatternRowDeleteMutation>(deletePatternMutation);
const [movePattern]
= useMutation<DetectionPatternRowMoveMutation>(movePatternMutation);
= useMutation<TrackerPatternRowMoveMutation>(movePatternMutation);
const [updatePattern, isUpdating]
= useMutation<DetectionPatternRowUpdateMutation>(updatePatternMutation);
= useMutation<TrackerPatternRowUpdateMutation>(updatePatternMutation);
const handleDelete = () => {
confirm(
@@ -276,7 +274,7 @@ export function DetectionPatternRow({ patternKey, connectionId }: DetectionPatte
if (isEditing) {
return (
<DetectionPatternRowEdit
<TrackerPatternRowEdit
pattern={pattern.displayName}
description={pattern.description}
maxAgeSeconds={pattern.maxAgeSeconds ?? null}

View File

@@ -22,7 +22,7 @@ interface FormValues {
description: string;
}
interface DetectionPatternRowEditProps {
interface TrackerPatternRowEditProps {
pattern: string;
description: string;
maxAgeSeconds: number | null;
@@ -31,14 +31,14 @@ interface DetectionPatternRowEditProps {
onCancel: () => void;
}
export function DetectionPatternRowEdit({
export function TrackerPatternRowEdit({
pattern,
description,
maxAgeSeconds,
isUpdating,
onSave,
onCancel,
}: DetectionPatternRowEditProps) {
}: TrackerPatternRowEditProps) {
const { __ } = useTranslate();
const initial = fromMaxAgeSeconds(maxAgeSeconds);

View File

@@ -65,9 +65,14 @@ export const cookieBannerRoutes = [
Component: lazy(() => import("#/pages/organizations/cookie-banners/configuration/consent-records/CookieBannerConsentRecordsPageLoader")),
},
{
path: "detection",
path: "trackers",
Fallback: LinkCardSkeleton,
Component: lazy(() => import("#/pages/organizations/cookie-banners/configuration/detection/CookieBannerDetectionPageLoader")),
Component: lazy(() => import("#/pages/organizations/cookie-banners/configuration/trackers/CookieBannerTrackersPageLoader")),
},
{
path: "resources",
Fallback: LinkCardSkeleton,
Component: lazy(() => import("#/pages/organizations/cookie-banners/configuration/resources/CookieBannerResourcesPageLoader")),
},
],
},