186 lines
5.4 KiB
Svelte
186 lines
5.4 KiB
Svelte
<script lang="ts">
|
|
import { JobService, HelpersService, ResourceService, SettingService } from '$lib/gen'
|
|
import { untrack } from 'svelte'
|
|
import { Alert, Button } from './common'
|
|
import S3FilePickerInner from './S3FilePickerInner.svelte'
|
|
import { workspaceStore } from '$lib/stores'
|
|
import { Loader, Loader2 } from 'lucide-svelte'
|
|
import { hubPaths } from '$lib/hub'
|
|
import { tryEvery } from '$lib/utils'
|
|
|
|
let s3FilePicker: S3FilePickerInner | undefined = $state()
|
|
|
|
let isLoadingCommitHash = $state(false)
|
|
let isLoadingRepoClone = $state(false)
|
|
let isCheckingPathExists = $state(false)
|
|
let pathExists = $state<boolean | null>(null)
|
|
let error = $state<string | null>(null)
|
|
|
|
interface Props {
|
|
gitRepoResourcePath: string
|
|
gitSshIdentity?: string[]
|
|
commitHashInput?: string
|
|
}
|
|
|
|
let { gitRepoResourcePath, gitSshIdentity, commitHashInput = $bindable() }: Props = $props()
|
|
|
|
let commitHash = $derived(commitHashInput);
|
|
|
|
async function populateS3WithGitRepo() {
|
|
const workspace = $workspaceStore
|
|
if (!workspace) return
|
|
|
|
const payload = {
|
|
workspace: workspace,
|
|
resource_path: gitRepoResourcePath,
|
|
git_ssh_identity: gitSshIdentity,
|
|
commit: commitHash,
|
|
}
|
|
|
|
isLoadingRepoClone = true
|
|
const jobId = await JobService.runScriptByPath({
|
|
workspace,
|
|
path: hubPaths.cloneRepoToS3forGitRepoViewer,
|
|
requestBody: payload,
|
|
skipPreprocessor: true
|
|
})
|
|
|
|
let jobSuccess = false
|
|
await tryEvery({
|
|
tryCode: async () => {
|
|
const testResult = await JobService.getCompletedJob({ workspace, id: jobId })
|
|
jobSuccess = !!testResult.success
|
|
if (jobSuccess) {
|
|
await JobService.getCompletedJobResult({ workspace, id: jobId })
|
|
} else {
|
|
error = (testResult.result as any).error.message ?? "Failed to clone"
|
|
}
|
|
},
|
|
timeoutCode: async () => {
|
|
try {
|
|
await JobService.cancelQueuedJob({
|
|
workspace,
|
|
id: jobId,
|
|
requestBody: { reason: `job timed out after 60s` }
|
|
})
|
|
} catch (err) {}
|
|
},
|
|
interval: 1000,
|
|
timeout: 60000
|
|
})
|
|
isLoadingRepoClone = false
|
|
if (jobSuccess) {
|
|
pathExists = true
|
|
}
|
|
}
|
|
|
|
async function fetchGitRepoData() {
|
|
try {
|
|
error = null
|
|
// Step 1: Fetch commit hash if not provided
|
|
if (!commitHash) {
|
|
isLoadingCommitHash = true
|
|
error = null
|
|
const result = await ResourceService.getGitCommitHash({
|
|
workspace: $workspaceStore!,
|
|
path: gitRepoResourcePath,
|
|
gitSshIdentity: gitSshIdentity?.join(",")
|
|
})
|
|
|
|
commitHashInput = result.commit_hash
|
|
isLoadingCommitHash = false
|
|
}
|
|
|
|
// Step 2: Check if S3 path exists
|
|
if (commitHash) {
|
|
isCheckingPathExists = true
|
|
|
|
const s3Path = `gitrepos/${$workspaceStore}/${gitRepoResourcePath}/${commitHash}/`
|
|
|
|
const pathCheck = await HelpersService.checkS3FolderExists({
|
|
workspace: $workspaceStore!,
|
|
fileKey: s3Path
|
|
})
|
|
|
|
pathExists = pathCheck.exists && pathCheck.is_folder
|
|
isCheckingPathExists = false
|
|
}
|
|
} catch (err: any) {
|
|
error = `Failed to load git repository ${gitRepoResourcePath}: ${err.status} - ${err.message || 'Unknown error'}: ${err.body}`
|
|
isLoadingCommitHash = false
|
|
isCheckingPathExists = false
|
|
}
|
|
}
|
|
|
|
$effect(() => {
|
|
;[commitHashInput, gitRepoResourcePath]
|
|
untrack(() => {
|
|
fetchGitRepoData()
|
|
})
|
|
|
|
})
|
|
|
|
$effect(() => {
|
|
;[commitHash, pathExists, isCheckingPathExists, isLoadingCommitHash]
|
|
untrack(() => {
|
|
s3FilePicker?.open(undefined)
|
|
})
|
|
})
|
|
</script>
|
|
|
|
{#if error}
|
|
<Alert type="error" title="Error Loading Repository">
|
|
<p>{error}</p>
|
|
</Alert>
|
|
{:else if isLoadingCommitHash}
|
|
<div class="flex items-center gap-2 p-4">
|
|
<Loader2 class="h-4 w-4 animate-spin" />
|
|
<span class="text-secondary">Fetching latest commit hash...</span>
|
|
</div>
|
|
{:else if isLoadingRepoClone}
|
|
<div class="flex items-center gap-2 p-4">
|
|
<Loader class="h-4 w-4 animate-spin" />
|
|
<span class="text-secondary">Cloning repository...</span>
|
|
</div>
|
|
{:else if commitHash && isCheckingPathExists}
|
|
<div class="flex items-center gap-2 p-4">
|
|
<Loader2 class="h-4 w-4 animate-spin" />
|
|
<span class="text-secondary">Checking repository availability...</span>
|
|
</div>
|
|
{:else if commitHash && pathExists === false}
|
|
<div class="p-4 space-y-3">
|
|
<Alert type="warning" title="Repository Not Available">
|
|
<p>The git repository content is not yet available in storage.</p>
|
|
</Alert>
|
|
<Button onclick={populateS3WithGitRepo} color="blue">Load Repository Contents</Button>
|
|
</div>
|
|
{:else if commitHash && pathExists === true}
|
|
<S3FilePickerInner
|
|
bind:this={s3FilePicker}
|
|
readOnlyMode
|
|
hideS3SpecificDetails
|
|
rootPath={`gitrepos/${$workspaceStore}/${gitRepoResourcePath}/${commitHash}/`}
|
|
listStoredFilesRequest={HelpersService.listGitRepoFiles}
|
|
loadFilePreviewRequest={HelpersService.loadGitRepoFilePreview}
|
|
testConnectionRequest={(async (_d) => {
|
|
const bucketConfig: any = await SettingService.getGlobal({ key: 'object_store_cache_config' })
|
|
return SettingService.testObjectStorageConfig({
|
|
requestBody: bucketConfig
|
|
})
|
|
}) as any}
|
|
loadFileMetadataRequest={HelpersService.loadGitRepoFileMetadata}
|
|
>
|
|
{#snippet replaceUnauthorizedWarning()}
|
|
<div class="mb-2">
|
|
<Alert type="error" title="Cannot view git repo">
|
|
<p>
|
|
The git repo resource you are trying to access either doesn't exist or you don't have
|
|
access to it. Make sure the resource path is correct and that you have visibility over
|
|
the resource.
|
|
</p>
|
|
</Alert>
|
|
</div>
|
|
{/snippet}
|
|
</S3FilePickerInner>
|
|
{/if}
|