mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
feat(backend): expose tag in the job (#1486)
* fix * update tag * update tag * update tag * fix
This commit is contained in:
@@ -3261,6 +3261,7 @@ paths:
|
||||
- $ref: "#/components/parameters/Running"
|
||||
- $ref: "#/components/parameters/ArgsFilter"
|
||||
- $ref: "#/components/parameters/ResultFilter"
|
||||
- $ref: "#/components/parameters/Tag"
|
||||
responses:
|
||||
"200":
|
||||
description: All available queued jobs
|
||||
@@ -3291,6 +3292,7 @@ paths:
|
||||
- $ref: "#/components/parameters/JobKinds"
|
||||
- $ref: "#/components/parameters/ArgsFilter"
|
||||
- $ref: "#/components/parameters/ResultFilter"
|
||||
- $ref: "#/components/parameters/Tag"
|
||||
- name: is_skipped
|
||||
description: is the job skipped
|
||||
in: query
|
||||
@@ -3328,6 +3330,7 @@ paths:
|
||||
- $ref: "#/components/parameters/StartedAfter"
|
||||
- $ref: "#/components/parameters/JobKinds"
|
||||
- $ref: "#/components/parameters/ArgsFilter"
|
||||
- $ref: "#/components/parameters/Tag"
|
||||
- $ref: "#/components/parameters/ResultFilter"
|
||||
- name: is_skipped
|
||||
description: is the job skipped
|
||||
@@ -4886,6 +4889,12 @@ components:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
Tag:
|
||||
name: tag
|
||||
description: filter on jobs with a given tag/worker group
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
ResultFilter:
|
||||
name: result
|
||||
description: filter on jobs containing those result as a json subset (@> in postgres)
|
||||
|
||||
@@ -326,6 +326,7 @@ pub struct CompletedJob {
|
||||
pub visible_to_owner: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mem_peak: Option<i32>,
|
||||
pub tag: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
@@ -410,6 +411,7 @@ pub struct ListQueueQuery {
|
||||
pub suspended: Option<bool>,
|
||||
// filter by matching a subset of the args using base64 encoded json subset
|
||||
pub args: Option<String>,
|
||||
pub tag: Option<String>,
|
||||
}
|
||||
|
||||
fn list_queue_jobs_query(w_id: &str, lq: &ListQueueQuery, fields: &[&str]) -> SqlBuilder {
|
||||
@@ -432,6 +434,9 @@ fn list_queue_jobs_query(w_id: &str, lq: &ListQueueQuery, fields: &[&str]) -> Sq
|
||||
if let Some(cb) = &lq.created_by {
|
||||
sqlb.and_where_eq("created_by", "?".bind(cb));
|
||||
}
|
||||
if let Some(t) = &lq.tag {
|
||||
sqlb.and_where_eq("tag", "?".bind(t));
|
||||
}
|
||||
if let Some(r) = &lq.running {
|
||||
sqlb.and_where_eq("running", &r);
|
||||
}
|
||||
@@ -564,6 +569,7 @@ async fn list_jobs(
|
||||
job_kinds: lq.job_kinds,
|
||||
suspended: lq.suspended,
|
||||
args: lq.args,
|
||||
tag: lq.tag,
|
||||
},
|
||||
&[
|
||||
"'QueuedJob' as typ",
|
||||
@@ -1106,6 +1112,7 @@ struct UnifiedJob {
|
||||
visible_to_owner: bool,
|
||||
suspend: Option<i32>,
|
||||
mem_peak: Option<i32>,
|
||||
tag: String,
|
||||
}
|
||||
|
||||
impl From<UnifiedJob> for Job {
|
||||
@@ -1141,6 +1148,7 @@ impl From<UnifiedJob> for Job {
|
||||
email: uj.email,
|
||||
visible_to_owner: uj.visible_to_owner,
|
||||
mem_peak: uj.mem_peak,
|
||||
tag: uj.tag,
|
||||
}),
|
||||
"QueuedJob" => Job::QueuedJob(QueuedJob {
|
||||
workspace_id: uj.workspace_id,
|
||||
@@ -1176,6 +1184,7 @@ impl From<UnifiedJob> for Job {
|
||||
mem_peak: uj.mem_peak,
|
||||
root_job: None,
|
||||
leaf_jobs: None,
|
||||
tag: uj.tag,
|
||||
}),
|
||||
t => panic!("job type {} not valid", t),
|
||||
}
|
||||
@@ -1865,6 +1874,9 @@ fn list_completed_jobs_query(
|
||||
if let Some(h) = &lq.script_hash {
|
||||
sqlb.and_where_eq("script_hash", "?".bind(h));
|
||||
}
|
||||
if let Some(t) = &lq.tag {
|
||||
sqlb.and_where_eq("tag", "?".bind(t));
|
||||
}
|
||||
if let Some(cb) = &lq.created_by {
|
||||
sqlb.and_where_eq("created_by", "?".bind(cb));
|
||||
}
|
||||
@@ -1922,6 +1934,7 @@ pub struct ListCompletedQuery {
|
||||
pub args: Option<String>,
|
||||
// filter by matching a subset of the result using base64 encoded json subset
|
||||
pub result: Option<String>,
|
||||
pub tag: Option<String>,
|
||||
}
|
||||
|
||||
async fn list_completed_jobs(
|
||||
|
||||
@@ -79,6 +79,7 @@ pub struct QueuedJob {
|
||||
pub root_job: Option<Uuid>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub leaf_jobs: Option<serde_json::Value>,
|
||||
pub tag: String,
|
||||
}
|
||||
|
||||
impl QueuedJob {
|
||||
@@ -140,6 +141,7 @@ impl Default for QueuedJob {
|
||||
mem_peak: None,
|
||||
root_job: None,
|
||||
leaf_jobs: None,
|
||||
tag: "deno".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,9 +126,10 @@ pub async fn add_completed_job<R: rsmq_async::RsmqConnection + Clone + Send>(
|
||||
, email
|
||||
, visible_to_owner
|
||||
, mem_peak
|
||||
, tag
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, COALESCE($26, (EXTRACT('epoch' FROM (now())) - EXTRACT('epoch' FROM (COALESCE($6, now()))))*1000), $7, $8, $9,\
|
||||
$10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $27, $28, $29)
|
||||
$10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $27, $28, $29, $30)
|
||||
ON CONFLICT (id) DO UPDATE SET success = $7, result = $11, logs = concat(cj.logs, $12)",
|
||||
queued_job.workspace_id,
|
||||
queued_job.id,
|
||||
@@ -158,7 +159,8 @@ pub async fn add_completed_job<R: rsmq_async::RsmqConnection + Clone + Send>(
|
||||
duration: Option<i64>,
|
||||
queued_job.email,
|
||||
queued_job.visible_to_owner,
|
||||
mem_peak
|
||||
mem_peak,
|
||||
queued_job.tag,
|
||||
)
|
||||
.execute(&mut tx)
|
||||
.await
|
||||
|
||||
@@ -26,35 +26,22 @@
|
||||
let popupOnTop = true
|
||||
|
||||
$: open = $openStore === job?.id
|
||||
$: completed = job?.type === Job.type.COMPLETED_JOB
|
||||
$: running = job && `running` in job ? job.running : false
|
||||
$: logs = job?.logs || logs
|
||||
|
||||
async function instantOpen() {
|
||||
hovered = true
|
||||
if (!job) {
|
||||
return
|
||||
if (!open) {
|
||||
hovered = true
|
||||
if (!job) {
|
||||
return
|
||||
}
|
||||
popupOnTop = wrapper.getBoundingClientRect().top > POPUP_HEIGHT
|
||||
openStore.set(job.id)
|
||||
if (!loaded) {
|
||||
await tick()
|
||||
watchJob && watchJob(job.id)
|
||||
}
|
||||
} else {
|
||||
timeout && clearTimeout(timeout)
|
||||
}
|
||||
popupOnTop = wrapper.getBoundingClientRect().top > POPUP_HEIGHT
|
||||
openStore.set(job.id)
|
||||
if (!loaded) {
|
||||
await tick()
|
||||
watchJob && watchJob(job.id)
|
||||
}
|
||||
}
|
||||
|
||||
function staggeredOpen() {
|
||||
hovered = true
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
timeout = setTimeout(
|
||||
async () => {
|
||||
timeout = undefined
|
||||
await instantOpen()
|
||||
},
|
||||
loaded ? 100 : 300
|
||||
)
|
||||
}
|
||||
|
||||
function close() {
|
||||
@@ -70,6 +57,9 @@
|
||||
|
||||
function staggeredClose() {
|
||||
hovered = false
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
timeout = setTimeout(
|
||||
async () => {
|
||||
timeout = undefined
|
||||
@@ -96,17 +86,15 @@
|
||||
{/if}
|
||||
|
||||
<div
|
||||
on:mouseenter={staggeredOpen}
|
||||
on:mouseenter={instantOpen}
|
||||
on:mouseleave={staggeredClose}
|
||||
on:focusin={instantOpen}
|
||||
on:focusout={close}
|
||||
bind:this={wrapper}
|
||||
class="relative"
|
||||
>
|
||||
<slot {open} />
|
||||
{#if open}
|
||||
<div
|
||||
transition:fade|local={{ duration: 100 }}
|
||||
transition:fade|local={{ duration: 50 }}
|
||||
class="absolute z-50 {popupOnTop ? 'bottom-[35px]' : 'top-[35px]'} -left-10 bg-white rounded
|
||||
border border-gray-300 shadow-xl flex justify-start items-start w-[600px] h-80
|
||||
overflow-hidden"
|
||||
@@ -121,11 +109,11 @@
|
||||
<div>{new Date(job?.['scheduled_for']).toLocaleString()}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if completed}
|
||||
{#if job?.type === Job.type.COMPLETED_JOB}
|
||||
<DisplayResult {result} disableExpand />
|
||||
{:else if running}
|
||||
{:else if job && `running` in job ? job.running : false}
|
||||
<div class="text-sm font-semibold text-gray-600 mb-1"> Job is still running </div>
|
||||
<LogViewer content={logs} isLoading />
|
||||
<LogViewer content={job?.logs} isLoading />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -284,6 +284,9 @@
|
||||
{/if}
|
||||
{#if job && 'job_kind' in job}<Badge baseClass="ml-2" color="blue">{job.job_kind}</Badge>
|
||||
{/if}
|
||||
{#if job.tag && !['deno', 'python3', 'flow', 'other', 'go', 'bash', 'other', 'dependency'].includes(job.tag)}
|
||||
<Badge color="indigo">Worker group: {job.tag}</Badge>
|
||||
{/if}
|
||||
{#if !job.visible_to_owner}<Badge color="red"
|
||||
>only visible to you <Tooltip
|
||||
>The option to hide this run from the owner of this script or flow was activated</Tooltip
|
||||
|
||||
Reference in New Issue
Block a user