feat: image variants cache panel

This commit is contained in:
fsylvain committed 2026-10-08 21:13:32 +02:00
1 parent 951fef18ba
commit d768668014
53 files changed
+5809 -46

No files matched your search

+134
View File
@@ -3412,6 +3412,139 @@ const variantsStates: Record<string, VisualState> = {
}),
}
const cachePath = '/settings/media/cache'
const cacheBoardImages: [string, number, number][] = [
['north-wall.jpg', 6, 6082765],
['lime-plaster.jpg', 6, 5138022],
['kitchen-after.webp', 5, 4613734],
['kitchen-before.webp', 5, 4089446],
['floorboards.jpg', 5, 3774873],
['IMG_4471.jpg', 4, 3250585],
['stone-wall-detail.jpg', 4, 2936012],
['bathroom-tiles.png', 4, 2726297],
['roof-lantern.jpg', 3, 2411724],
['chimney-stack.jpg', 3, 2202009],
]
const cacheBoardStats = {
generated_files: 1284,
disk_used: 222298112,
variants_defined: 6,
variants_enabled: 5,
variants_disabled: 1,
rejected_requests: 37,
rejected_window_days: 7,
unused: { files: 312, bytes: 42991616, days: 30 },
by_variant: [
{ name: 'hero', enabled: true, files: 244, bytes: 88080384 },
{ name: 'card', enabled: true, files: 318, bytes: 60817408 },
{ name: 'print', enabled: false, files: 74, bytes: 22020096 },
{ name: 'thumb', enabled: true, files: 412, bytes: 22020096 },
{ name: 'square', enabled: true, files: 140, bytes: 19922944 },
{ name: 'og', enabled: true, files: 96, bytes: 9437184 },
],
top_images: cacheBoardImages.map(([filename, files, bytes], index) => ({
id: index + 1,
filename,
url: `/static/uploadedImages/${filename}`,
files,
bytes,
})),
}
const cacheEmptyStats = {
...cacheBoardStats,
generated_files: 0,
disk_used: 0,
unused: { files: 0, bytes: 0, days: 30 },
by_variant: [],
top_images: [],
}
const cacheStatsKey = 'GET /v1/image-variants/cache'
const cachePurgeKey = 'POST /v1/image-variants/cache/purge'
const cachePurgeAllResult = {
scope: 'all',
purged_files: 1284,
purged_bytes: 222298112,
failed_files: 0,
}
function cacheState(
statsMock: ApiMock = { status: 200, body: cacheBoardStats },
overrides: Record<string, ApiMock> = {},
steps?: VisualState['steps'],
): VisualState {
return {
path: cachePath,
api: { 'GET /v1/auth/me': variantsSession, [cacheStatsKey]: statsMock, ...overrides },
steps,
}
}
async function confirmPurgeAll(page: Page) {
await page.getByRole('button', { name: 'Purge all variants', exact: true }).first().click()
await page.getByRole('alertdialog').getByRole('textbox').fill('purge')
await page
.getByRole('alertdialog')
.getByRole('button', { name: 'Purge all variants', exact: true })
.click()
await page.mouse.move(0, 0)
}
const cacheStates: Record<string, VisualState> = {
'5a · Loaded': cacheState(),
'5b · Loading': cacheState({ status: 200, hang: true }),
'5c · Empty cache': cacheState({ status: 200, body: cacheEmptyStats }),
'5d · Purging': cacheState(
{ status: 200, body: cacheBoardStats },
{ [cachePurgeKey]: { status: 200, hang: true } },
confirmPurgeAll,
),
'5e · Purge done': cacheState(
{
status: 200,
bodyFor: (_url, call) => (call === 0 ? cacheBoardStats : cacheEmptyStats),
},
{ [cachePurgeKey]: { status: 200, body: cachePurgeAllResult } },
confirmPurgeAll,
),
'5f · Purge failed': cacheState(
{ status: 200, body: cacheBoardStats },
{
[cachePurgeKey]: {
status: 200,
body: {
...cachePurgeAllResult,
purged_files: 640,
purged_bytes: 111149056,
failed_files: 644,
},
},
},
confirmPurgeAll,
),
'5g · Error loading': cacheState({ status: 500 }),
'5h · Purge all: confirm': cacheState(undefined, {}, async (page) => {
await page.getByRole('button', { name: 'Purge all variants', exact: true }).first().click()
await page.getByRole('alertdialog').waitFor()
await page.getByRole('alertdialog').getByRole('textbox').fill('pur')
await page.mouse.move(0, 0)
}),
'5i · Purge all: confirm, typed': cacheState(undefined, {}, async (page) => {
await page.getByRole('button', { name: 'Purge all variants', exact: true }).first().click()
await page.getByRole('alertdialog').waitFor()
await page.getByRole('alertdialog').getByRole('textbox').fill('purge')
await page.mouse.move(0, 0)
}),
'5j · Purge unused: confirm': cacheState(undefined, {}, async (page) => {
await page.getByRole('button', { name: 'Purge unused', exact: true }).first().click()
await page.getByRole('alertdialog').waitFor()
await page.mouse.move(0, 0)
}),
}
const variantBoardSizes: Record<string, number> = {
thumb: 18432,
card: 65536,
@@ -4929,6 +5062,7 @@ export const visualStates: Record<string, Record<string, VisualState>> = {
},
'image-variants': {
...variantsStates,
...cacheStates,
...withVariantExceptions(variantsMediaStates),
...withVariantExceptions(variantsEditorStates),
},