assets in JobPreview

This commit is contained in:
Diego Imbert
2025-06-25 20:41:08 +02:00
parent 4e2a1b8ac9
commit d0b03533b9
3 changed files with 108 additions and 8 deletions

View File

@@ -12981,7 +12981,7 @@ paths:
- $ref: '#/components/parameters/WorkspaceId'
responses:
'200':
description: assets linked
description: all assets in the workspace
content:
application/json:
schema:
@@ -13005,6 +13005,32 @@ paths:
usage_kind:
$ref: '#/components/schemas/AssetUsageKind'
/w/{workspace}/assets/list_for_usage:
get:
summary: List all assets used by a given usage path
operationId: listAssetsForUsage
tags:
- asset
parameters:
- $ref: '#/components/parameters/WorkspaceId'
- $ref: '#/components/parameters/AssetUsageKind'
- $ref: '#/components/parameters/AssetUsagePath'
responses:
'200':
description: all assets used by the given usage path
content:
application/json:
schema:
type: array
items:
type: object
required: [path, kind]
properties:
path:
type: string
kind:
$ref: '#/components/schemas/AssetKind'
components:
securitySchemes:
bearerAuth:
@@ -13034,6 +13060,18 @@ components:
required: true
schema:
type: string
AssetUsageKind:
name: usage_kind
in: query
required: true
schema:
$ref: "#/components/schemas/AssetUsageKind"
AssetUsagePath:
name: usage_path
in: query
required: true
schema:
type: string
PublicationName:
name: publication
in: path

View File

@@ -1,15 +1,23 @@
use axum::{extract::{Path}, routing::{post, get}, Extension, Json, Router};
use axum::{
extract::{Path, Query},
routing::{get, post},
Extension, Json, Router,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use sqlx::{Postgres, Transaction};
use windmill_common::{db::UserDB, error::{JsonResult, Result}};
use windmill_common::{
db::UserDB,
error::{JsonResult, Result},
};
use crate::db::ApiAuthed;
pub fn workspaced_service() -> Router {
Router::new()
.route("/link", post(link_assets))
.route("/list", get(list_assets))
.route("/link", post(link_assets))
.route("/list", get(list_assets))
.route("/list_for_usage", get(list_assets_for_usage))
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Hash, Eq, sqlx::Type)]
@@ -71,7 +79,7 @@ async fn link_assets_internal(
sqlx::query!(
r#"INSERT INTO asset (workspace_id, path, kind, usage_path, usage_kind) VALUES ($1, $2, $3, $4, $5);"#,
w_id,
asset.path,
asset.path,
asset.kind as AssetKind,
body.usage_path,
body.usage_kind as AssetUsageKind
@@ -106,4 +114,34 @@ async fn list_assets(
.await?;
Ok(Json(assets))
}
}
#[derive(Deserialize)]
struct ListAssetForUsageQuery {
usage_kind: AssetUsageKind,
usage_path: String,
}
async fn list_assets_for_usage(
authed: ApiAuthed,
Path(w_id): Path<String>,
Query(ListAssetForUsageQuery { usage_kind, usage_path }): Query<ListAssetForUsageQuery>,
Extension(user_db): Extension<UserDB>,
) -> JsonResult<Vec<Value>> {
let assets = sqlx::query_scalar!(
r#"SELECT
jsonb_build_object(
'path', path,
'kind', kind
) as "list!: _"
FROM asset
WHERE workspace_id = $1 AND usage_path = $2 AND usage_kind = $3"#,
w_id,
usage_path,
usage_kind as AssetUsageKind
)
.fetch_all(&mut *user_db.begin(&authed).await?)
.await?;
Ok(Json(assets))
}

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { base } from '$lib/base'
import { ConcurrencyGroupsService, type Job, type WorkflowStatus } from '../../gen'
import { AssetService, ConcurrencyGroupsService, type Job, type WorkflowStatus } from '../../gen'
import TestJobLoader from '../TestJobLoader.svelte'
import DisplayResult from '../DisplayResult.svelte'
import JobArgs from '../JobArgs.svelte'
@@ -17,6 +17,8 @@
import { isFlowPreview, isScriptPreview, truncateRev } from '$lib/utils'
import { createEventDispatcher } from 'svelte'
import { ListFilter } from 'lucide-svelte'
import { usePromise } from '$lib/svelte5Utils.svelte'
import { formatAsset } from '../assets/lib'
export let id: string
export let blankLink = false
@@ -53,6 +55,17 @@
let viewTab = 'result'
let assets = usePromise(async () =>
(job?.job_kind === 'flow' || job?.job_kind === 'script') && job?.script_path
? AssetService.listAssetsForUsage({
workspace: workspace ?? $workspaceStore ?? '',
usageKind: job.job_kind,
usagePath: job.script_path
})
: undefined
)
$: job?.job_kind && job.script_path && assets.refresh()
function asWorkflowStatus(x: any): Record<string, WorkflowStatus> {
return x as Record<string, WorkflowStatus>
}
@@ -161,6 +174,17 @@
/>
</div>
{#if assets.value}
<span class="font-semibold text-xs leading-6">Assets</span>
<ul class="w-full">
{#each assets.value as asset}
<li class="!list-disc ml-6 text-sm">
<p class="truncate">{formatAsset(asset)}</p>
</li>
{/each}
</ul>
{/if}
{#if job?.type === 'CompletedJob'}
<span class="font-semibold text-xs leading-6">Results</span>
{/if}