mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-21 00:02:30 +00:00
fix: custom tag helper
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT EXISTS(SELECT 1 FROM folder WHERE name = $1 AND workspace_id = $2 AND $3 = ANY(owners))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "exists",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "6a0b04a34032ae0e28bbb4895ad8409185d273c022c4971329f5bce85097bc22"
|
||||
}
|
||||
@@ -202,6 +202,7 @@ async fn create_folder(
|
||||
));
|
||||
}
|
||||
|
||||
if let Err(e) =
|
||||
sqlx::query_as!(
|
||||
Folder,
|
||||
"INSERT INTO folder (workspace_id, name, display_name, owners, extra_perms, summary, created_by, edited_at) VALUES ($1, $2, $3, $4, $5, $6, $7, now())",
|
||||
@@ -214,7 +215,38 @@ async fn create_folder(
|
||||
authed.username
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
.await {
|
||||
let exists_for_user = sqlx::query_scalar!(
|
||||
"SELECT EXISTS(SELECT 1 FROM folder WHERE name = $1 AND workspace_id = $2 AND $3 = ANY(owners))",
|
||||
ng.name,
|
||||
w_id,
|
||||
authed.username
|
||||
)
|
||||
.fetch_one(&mut *tx)
|
||||
.await?
|
||||
.unwrap_or(false);
|
||||
let exists = sqlx::query_scalar!(
|
||||
"SELECT EXISTS(SELECT 1 FROM folder WHERE name = $1 AND workspace_id = $2)",
|
||||
ng.name,
|
||||
w_id
|
||||
)
|
||||
.fetch_one(&db)
|
||||
.await?
|
||||
.unwrap_or(false);
|
||||
if !exists_for_user && exists {
|
||||
return Err(windmill_common::error::Error::BadRequest(format!(
|
||||
"Folder '{}' already exists in workspace '{}' but you do not have permission to read to it", ng.name, w_id
|
||||
)));
|
||||
} else if exists {
|
||||
return Err(windmill_common::error::Error::BadRequest(format!(
|
||||
"Folder '{}' already exists in workspace '{}'", ng.name, w_id
|
||||
)));
|
||||
} else {
|
||||
return Err(windmill_common::error::Error::InternalErr(format!(
|
||||
"Failed to create folder: {}", e
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
audit_log(
|
||||
&mut *tx,
|
||||
|
||||
@@ -32,6 +32,34 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const customTagRegex = /^([\w-]+)\(((?:[\w-]+\+)*[\w-]+|(?:\^[\w-]+)+)\)$/
|
||||
const dynamicTagRegex = /\$args\[((?:\w+\.)*\w+)\]/
|
||||
|
||||
let dynamicTag = $derived.by(() => {
|
||||
let r = newTag.trim()
|
||||
if (r == '') return undefined
|
||||
let matched = r.match(dynamicTagRegex)
|
||||
return matched?.[1]
|
||||
})
|
||||
|
||||
let extractedCustomTag = $derived.by(() => {
|
||||
let r = newTag.trim()
|
||||
if (r == '') return undefined
|
||||
let matched = r.match(customTagRegex)
|
||||
console.log(matched)
|
||||
let tag = matched?.[1]
|
||||
let workspaces_raw = matched?.[2]
|
||||
let tag_type = workspaces_raw?.includes('^') ? 'exclude' : 'include'
|
||||
if (tag_type == 'exclude') {
|
||||
workspaces_raw = workspaces_raw?.slice(1)
|
||||
}
|
||||
let workspaces = workspaces_raw?.split(tag_type == 'include' ? '+' : '^')
|
||||
if (!workspaces_raw || workspaces_raw?.length == 0) {
|
||||
return undefined
|
||||
}
|
||||
return { tag, workspaces, tag_type }
|
||||
})
|
||||
|
||||
loadCustomTags()
|
||||
</script>
|
||||
|
||||
@@ -64,6 +92,53 @@
|
||||
{/each}
|
||||
</div>
|
||||
<input type="text" bind:value={newTag} />
|
||||
{#if extractedCustomTag}
|
||||
<div class="text-2xs text-tertiary p-2 bg-gray-50 rounded border">
|
||||
<div class="font-medium mb-1">Workspace specific tag</div>
|
||||
<div>
|
||||
<b>Tag:</b>
|
||||
{extractedCustomTag.tag}
|
||||
</div>
|
||||
<div>
|
||||
<b>Workspaces:</b>
|
||||
{#if extractedCustomTag.tag_type == 'include'}
|
||||
{extractedCustomTag.workspaces?.join(', ')}
|
||||
{:else}
|
||||
All workspaces except {extractedCustomTag.workspaces?.join(', ')}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else if newTag.trim()}
|
||||
{#if newTag.includes('(') || newTag.includes(')') || newTag.includes('+') || newTag.includes('^') || ((newTag.includes('.') || newTag.includes('$args[')) && !dynamicTag)}
|
||||
<div class="text-2xs text-tertiary p-2 bg-gray-50 rounded border">
|
||||
<div class="font-medium mb-1 text-red-500">Invalid tag</div>
|
||||
<div>
|
||||
<b>Tag:</b>
|
||||
{newTag.trim()}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-2xs text-tertiary p-2 bg-gray-50 rounded border">
|
||||
<div class="font-medium mb-1">
|
||||
{#if newTag.includes('$workspace') || newTag.includes('$args')}
|
||||
Dynamic tag
|
||||
{:else}
|
||||
Simple tag
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<b>Tag:</b>
|
||||
{newTag.trim()}
|
||||
</div>
|
||||
{#if newTag.includes('$workspace') && !dynamicTag}
|
||||
<div>Interpolated tag based on workspace id the job was created in </div>
|
||||
{/if}
|
||||
{#if dynamicTag}
|
||||
<div>Interpolated tag based on args input of <b>{dynamicTag}</b></div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
@@ -96,13 +171,25 @@
|
||||
></span
|
||||
>
|
||||
<span class="text-2xs text-tertiary"
|
||||
>To exclude 'workspace1' and 'workspace2' from a tag, use <pre
|
||||
class="inline">tag(^workspace1^workspace2)</pre
|
||||
>To exclude 'workspace1' and 'workspace2' from a tag, use <pre class="inline"
|
||||
>tag(^workspace1^workspace2)</pre
|
||||
></span
|
||||
>
|
||||
<span class="text-2xs text-tertiary"
|
||||
>For dynamic tags based on the workspace, use <pre class="inline">$workspace</pre>, e.g:
|
||||
>For <a
|
||||
href="https://www.windmill.dev/docs/core_concepts/worker_groups#dynamic-tag"
|
||||
target="_blank">dynamic tags</a
|
||||
>
|
||||
based on the workspace, use <pre class="inline">$workspace</pre>, e.g:
|
||||
<pre class="inline">tag-$workspace</pre></span
|
||||
>
|
||||
<span class="text-2xs text-tertiary"
|
||||
>For <a
|
||||
href="https://www.windmill.dev/docs/core_concepts/worker_groups#dynamic-tag"
|
||||
target="_blank">dynamic tags</a
|
||||
>
|
||||
based on args input, use <pre class="inline">$args[a.b.c]</pre> where
|
||||
<pre class="inline">a.b.c</pre> is the path to the value in the args object</span
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user