S3 object Preview

This commit is contained in:
Diego Imbert
2025-06-25 18:59:25 +02:00
parent 7f9a4dee60
commit 761891f0c1
3 changed files with 51 additions and 10 deletions
@@ -16,7 +16,14 @@
import { workspaceStore } from '$lib/stores'
import { HelpersService } from '$lib/gen'
import { base } from '$lib/base'
import { displayDate, displaySize, emptyString, sendUserToast } from '$lib/utils'
import {
displayDate,
displaySize,
emptyString,
parseS3Object,
sendUserToast,
type S3Object
} from '$lib/utils'
import { Alert, Button, Drawer } from './common'
import DrawerContent from './common/drawer/DrawerContent.svelte'
import Section from './Section.svelte'
@@ -377,9 +384,8 @@
}
let storage: string | undefined = $state(undefined)
export async function open(
preSelectedFileKey: { s3: string; storage?: string } | undefined = undefined
) {
export async function open(_preSelectedFileKey: S3Object | undefined = undefined) {
const preSelectedFileKey = _preSelectedFileKey && parseS3Object(_preSelectedFileKey)
storage = preSelectedFileKey?.storage
if (preSelectedFileKey !== undefined) {
initialFileKey = { ...preSelectedFileKey }
+19
View File
@@ -1433,3 +1433,22 @@ export function scroll_into_view_if_needed_polyfill(elem: Element, centerIfNeede
}
export const editorPositionMap: Record<string, IPosition> = {}
export type S3Uri = `s3://${string}/${string}`
export type S3Object =
| S3Uri
| {
s3: string
storage?: string
}
export function parseS3Object(s3Object: S3Object): { s3: string; storage?: string } {
if (typeof s3Object === 'object') return s3Object
const match = s3Object.match(/^s3:\/\/([^/]*)\/(.*)$/)
return { storage: match?.[1] || undefined, s3: match?.[2] ?? '' }
}
export function isS3Uri(uri: string): uri is S3Uri {
const match = uri.match(/^s3:\/\/([^/]*)\/(.*)$/)
return !!match && match.length === 3
}
@@ -4,13 +4,14 @@
import { Button, DrawerContent } from '$lib/components/common'
import Drawer from '$lib/components/common/drawer/Drawer.svelte'
import PageHeader from '$lib/components/PageHeader.svelte'
import S3FilePicker from '$lib/components/S3FilePicker.svelte'
import { Cell, DataTable } from '$lib/components/table'
import Head from '$lib/components/table/Head.svelte'
import { AssetService } from '$lib/gen'
import { userStore, workspaceStore, userWorkspaces } from '$lib/stores'
import { usePaginated } from '$lib/svelte5Utils.svelte'
import { pluralize } from '$lib/utils'
import { RefreshCw } from 'lucide-svelte'
import { isS3Uri, pluralize } from '$lib/utils'
import { File, RefreshCw } from 'lucide-svelte'
let assets = usePaginated(async (page) => {
return {
@@ -23,6 +24,7 @@
})
let viewOccurences: (typeof assets)['items'][number] | undefined = $state()
let s3FilePicker: S3FilePicker | undefined = $state()
</script>
{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find((_) => _.id === $workspaceStore)?.operator_settings?.resources}
@@ -42,6 +44,7 @@
<tr>
<Cell head first>Asset name</Cell>
<Cell head></Cell>
<Cell head></Cell>
</tr>
</Head>
<tbody class="divide-y bg-surface">
@@ -54,6 +57,19 @@
{pluralize(item.usages.length, 'occurrence')}
</a>
</Cell>
<Cell>
{#if item.kind === 's3object'}
<Button
size="xs"
variant="border"
spacingSize="xs2"
btnClasses="mt-1 w-24"
on:click={async () => isS3Uri(assetUri) && s3FilePicker?.open(assetUri)}
>
<File size={18} /> View
</Button>
{/if}
</Cell>
</tr>
{/each}
<tr class="w-full">
@@ -81,10 +97,10 @@
>
<DrawerContent title="Asset occurrences" on:close={() => (viewOccurences = undefined)}>
{#each viewOccurences?.usages ?? [] as u}
<div class="p-4">
<h3 class="text-lg font-semibold mb-2">{u.usage_kind}</h3>
<p class="text-sm text-gray-600 mb-2">{u.usage_path}</p>
</div>
<ul class="px-6">
<li class="text-sm list-disc">{u.usage_kind}/{u.usage_path}</li>
</ul>
{/each}
</DrawerContent>
</Drawer>
<S3FilePicker bind:this={s3FilePicker} readOnlyMode />