Show persistent for local-storage trackers

Local storage, IndexedDB, and cache storage have no expiry yet
persist until explicitly cleared, so a missing max-age should read
as "persistent", not "session" (the latter only fits cookies and
session storage, which end with the session or tab).

Thread the tracker type through humanizeSeconds (helpers) and
humanizeDuration (cookie-banner, with a localized persistent label)
and pass it at every console and banner call site. The consent
record query now selects trackerType so its duration column can
make the same distinction. This mirrors the Go HumanizedDuration
helper that already renders these types as persistent.

Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
Émile Ré
2026-06-19 10:35:19 +02:00
parent a4cc82441a
commit f1fc2dc0e0
7 changed files with 51 additions and 22 deletions

View File

@@ -49,6 +49,7 @@ export const cookieBannerConsentRecordPageQuery = graphql`
kind
cookies {
name
trackerType
maxAgeSeconds
description
}
@@ -235,7 +236,7 @@ export default function CookieBannerConsentRecordPage({
{cookie.name}
</td>
<td className="py-1 pr-4 text-txt-secondary">
{humanizeSeconds(cookie.maxAgeSeconds ?? null)}
{humanizeSeconds(cookie.maxAgeSeconds ?? null, cookie.trackerType)}
</td>
<td className="py-1 text-txt-secondary">
{cookie.description}

View File

@@ -795,7 +795,7 @@ export function CategorySection({ categoryKey, connectionId }: CategorySectionPr
})()}
</Td>
<Td className="text-sm text-muted-foreground">
{humanizeSeconds(pattern.maxAgeSeconds ?? null)}
{humanizeSeconds(pattern.maxAgeSeconds ?? null, pattern.trackerType)}
</Td>
<Td>
<div className="flex items-center gap-1">

View File

@@ -161,7 +161,7 @@ export function TrackerPatternPropertiesSection({
</PropertyRow>
<PropertyRow label={__("Max Age")}>
<span className="text-sm">
{humanizeSeconds(pattern.maxAgeSeconds ?? null)}
{humanizeSeconds(pattern.maxAgeSeconds ?? null, pattern.trackerType)}
</span>
</PropertyRow>
{pattern.description && (

View File

@@ -28,7 +28,6 @@ import {
} from "@probo/ui";
import { useState } from "react";
import { graphql, useFragment, useMutation } from "react-relay";
import { ConnectionHandler } from "relay-runtime";
import type { TrackerPatternRowDeleteMutation } from "#/__generated__/core/TrackerPatternRowDeleteMutation.graphql";
import type { TrackerPatternRowFragment$key } from "#/__generated__/core/TrackerPatternRowFragment.graphql";
@@ -94,6 +93,8 @@ const movePatternMutation = graphql`
id
cookieCategory {
id
name
kind
}
}
cookieBanner {
@@ -214,17 +215,6 @@ export function TrackerPatternRow({ patternKey, connectionId }: TrackerPatternRo
targetCookieCategoryId: targetCategoryId,
},
},
updater(store) {
const payload = store.getRootField("moveTrackerPatternToCategory");
if (!payload?.getLinkedRecord("trackerPattern")) {
return;
}
const conn = store.get(connectionId);
if (conn) {
ConnectionHandler.deleteNode(conn, pattern.id);
}
},
onCompleted(_, errors) {
if (errors?.length) {
toast({ title: __("Error"), description: errors[0].message, variant: "error" });
@@ -392,7 +382,7 @@ export function TrackerPatternRow({ patternKey, connectionId }: TrackerPatternRo
</div>
</Td>
<Td>
<span className="pl-2">{humanizeSeconds(pattern.maxAgeSeconds ?? null)}</span>
<span className="pl-2">{humanizeSeconds(pattern.maxAgeSeconds ?? null, pattern.trackerType)}</span>
</Td>
<Td>
{pattern.lastMatchedAt