feat(delay-profiles, regular-expressions): add created_at and updated_at fields to profiles and expressions

This commit is contained in:
Sam Chau
2026-01-02 23:43:24 +10:30
parent 897cfa6b06
commit e79a2babe9
6 changed files with 85 additions and 7 deletions

View File

@@ -23,7 +23,9 @@ export async function list(cache: PCDCache): Promise<DelayProfileTableRow[]> {
'torrent_delay',
'bypass_if_highest_quality',
'bypass_if_above_custom_format_score',
'minimum_custom_format_score'
'minimum_custom_format_score',
'created_at',
'updated_at'
])
.orderBy('name')
.execute();
@@ -70,6 +72,8 @@ export async function list(cache: PCDCache): Promise<DelayProfileTableRow[]> {
bypass_if_highest_quality: profile.bypass_if_highest_quality === 1,
bypass_if_above_custom_format_score: profile.bypass_if_above_custom_format_score === 1,
minimum_custom_format_score: profile.minimum_custom_format_score,
tags: tagsMap.get(profile.id) || []
tags: tagsMap.get(profile.id) || [],
created_at: profile.created_at,
updated_at: profile.updated_at
}));
}

View File

@@ -18,4 +18,6 @@ export interface DelayProfileTableRow {
bypass_if_above_custom_format_score: boolean;
minimum_custom_format_score: number | null;
tags: Tag[];
created_at: string;
updated_at: string;
}

View File

@@ -15,7 +15,7 @@ export async function list(cache: PCDCache): Promise<RegularExpressionTableRow[]
// 1. Get all regular expressions
const expressions = await db
.selectFrom('regular_expressions')
.select(['id', 'name', 'pattern', 'regex101_id', 'description'])
.select(['id', 'name', 'pattern', 'regex101_id', 'description', 'created_at', 'updated_at'])
.orderBy('name')
.execute();
@@ -58,6 +58,8 @@ export async function list(cache: PCDCache): Promise<RegularExpressionTableRow[]
pattern: expression.pattern,
regex101_id: expression.regex101_id,
description: expression.description,
tags: tagsMap.get(expression.id) || []
tags: tagsMap.get(expression.id) || [],
created_at: expression.created_at,
updated_at: expression.updated_at
}));
}

View File

@@ -12,4 +12,6 @@ export interface RegularExpressionTableRow {
regex101_id: string | null;
description: string | null;
tags: Tag[];
created_at: string;
updated_at: string;
}

View File

@@ -2,12 +2,24 @@
import Table from '$ui/table/Table.svelte';
import type { Column } from '$ui/table/types';
import type { DelayProfileTableRow } from '$pcd/queries/delayProfiles';
import { Tag, Clock, Zap, Shield } from 'lucide-svelte';
import { Tag, Clock, Zap, Shield, Calendar } from 'lucide-svelte';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
export let profiles: DelayProfileTableRow[];
function formatDate(dateString: string): string {
// SQLite stores timestamps without timezone info, treat as UTC
const date = new Date(dateString + 'Z');
return date.toLocaleString(undefined, {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
function handleRowClick(row: DelayProfileTableRow) {
const databaseId = $page.params.databaseId;
goto(`/delay-profiles/${databaseId}/${row.id}`);
@@ -66,7 +78,7 @@
header: 'Protocol',
headerIcon: Zap,
align: 'left',
width: 'w-40',
width: 'w-44',
cell: (row: DelayProfileTableRow) => ({
html: `<span class="font-mono text-xs bg-neutral-100 dark:bg-neutral-800 px-2 py-0.5 rounded">${formatProtocol(row.preferred_protocol)}</span>`
})
@@ -113,6 +125,28 @@
`
};
}
},
{
key: 'updated_at',
header: 'Updated',
headerIcon: Calendar,
align: 'left',
width: 'w-44',
sortable: true,
cell: (row: DelayProfileTableRow) => ({
html: `<span class="text-xs text-neutral-500 dark:text-neutral-400">${formatDate(row.updated_at)}</span>`
})
},
{
key: 'created_at',
header: 'Created',
headerIcon: Calendar,
align: 'left',
width: 'w-44',
sortable: true,
cell: (row: DelayProfileTableRow) => ({
html: `<span class="text-xs text-neutral-500 dark:text-neutral-400">${formatDate(row.created_at)}</span>`
})
}
];
</script>

View File

@@ -2,13 +2,25 @@
import Table from '$ui/table/Table.svelte';
import type { Column } from '$ui/table/types';
import type { RegularExpressionTableRow } from '$pcd/queries/regularExpressions';
import { Tag, Code, FileText, Link } from 'lucide-svelte';
import { Tag, Code, FileText, Link, Calendar } from 'lucide-svelte';
import { marked } from 'marked';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
export let expressions: RegularExpressionTableRow[];
function formatDate(dateString: string): string {
// SQLite stores timestamps without timezone info, treat as UTC
const date = new Date(dateString + 'Z');
return date.toLocaleString(undefined, {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
function handleRowClick(row: RegularExpressionTableRow) {
const databaseId = $page.params.databaseId;
goto(`/regular-expressions/${databaseId}/${row.id}`);
@@ -92,6 +104,28 @@
? `<a href="https://regex101.com/r/${escapeHtml(row.regex101_id)}" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 font-mono text-xs text-accent-600 hover:text-accent-700 dark:text-accent-400 dark:hover:text-accent-300 hover:underline">${escapeHtml(row.regex101_id)}<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a>`
: `<span class="text-neutral-400">-</span>`
})
},
{
key: 'updated_at',
header: 'Updated',
headerIcon: Calendar,
align: 'left',
width: 'w-44',
sortable: true,
cell: (row: RegularExpressionTableRow) => ({
html: `<span class="text-xs text-neutral-500 dark:text-neutral-400">${formatDate(row.updated_at)}</span>`
})
},
{
key: 'created_at',
header: 'Created',
headerIcon: Calendar,
align: 'left',
width: 'w-44',
sortable: true,
cell: (row: RegularExpressionTableRow) => ({
html: `<span class="text-xs text-neutral-500 dark:text-neutral-400">${formatDate(row.created_at)}</span>`
})
}
];
</script>