mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-13 00:03:57 +00:00
198 lines
4.8 KiB
Svelte
198 lines
4.8 KiB
Svelte
<script lang="ts">
|
|
import { type Meta, pathToMeta } from '$lib/common'
|
|
|
|
import {
|
|
FlowService,
|
|
ResourceService,
|
|
ScheduleService,
|
|
ScriptService,
|
|
VariableService,
|
|
type Group
|
|
} from '$lib/gen'
|
|
import { GroupService } from '$lib/gen'
|
|
import Tooltip from './Tooltip.svelte'
|
|
import { userStore, workspaceStore } from '$lib/stores'
|
|
import { sleep } from '$lib/utils'
|
|
|
|
type PathKind = 'resource' | 'script' | 'variable' | 'flow' | 'schedule'
|
|
export let meta: Meta = {
|
|
ownerKind: 'user',
|
|
owner: '',
|
|
name: ''
|
|
}
|
|
export let namePlaceholder = ''
|
|
export let initialPath: string
|
|
export let path = ''
|
|
export let error = ''
|
|
|
|
export let kind: PathKind
|
|
|
|
let groups: Group[] = []
|
|
|
|
$: {
|
|
path = [meta.ownerKind === 'group' ? 'g' : 'u', meta.owner, meta.name].join('/')
|
|
}
|
|
|
|
export function getPath() {
|
|
return path
|
|
}
|
|
|
|
export async function reset() {
|
|
if (path == '' || path == 'u//') {
|
|
meta.ownerKind = 'user'
|
|
|
|
while ($userStore == undefined) {
|
|
await sleep(500)
|
|
}
|
|
meta.owner = $userStore!.username
|
|
meta.name = ''
|
|
} else {
|
|
meta = pathToMeta(path)
|
|
}
|
|
}
|
|
|
|
$: validate(meta, path, kind)
|
|
|
|
async function loadGroups(): Promise<void> {
|
|
groups = await GroupService.listGroups({ workspace: $workspaceStore! })
|
|
meta.owner = meta.owner
|
|
}
|
|
|
|
async function validate(meta: Meta, path: string, kind: PathKind) {
|
|
validateName(meta) && (await validatePath(path, kind))
|
|
}
|
|
|
|
let validateTimeout: NodeJS.Timeout | undefined = undefined
|
|
|
|
async function validatePath(path: string, kind: PathKind): Promise<void> {
|
|
if (initialPath != '' && initialPath != path) {
|
|
if (validateTimeout) {
|
|
clearTimeout(validateTimeout)
|
|
}
|
|
validateTimeout = setTimeout(async () => {
|
|
if (
|
|
initialPath != '' &&
|
|
initialPath != path &&
|
|
((kind == 'flow' &&
|
|
(await FlowService.existsFlowByPath({ workspace: $workspaceStore!, path: path }))) ||
|
|
(kind == 'script' &&
|
|
(await ScriptService.existsScriptByPath({
|
|
workspace: $workspaceStore!,
|
|
path: path
|
|
}))) ||
|
|
(kind == 'resource' &&
|
|
(await ResourceService.existsResource({
|
|
workspace: $workspaceStore!,
|
|
path: path
|
|
}))) ||
|
|
(kind == 'variable' &&
|
|
(await VariableService.existsVariable({
|
|
workspace: $workspaceStore!,
|
|
path: path
|
|
}))) ||
|
|
(kind == 'schedule' &&
|
|
(await ScheduleService.existsSchedule({ workspace: $workspaceStore!, path: path }))))
|
|
) {
|
|
error = 'path already used'
|
|
} else if (validateName(meta)) {
|
|
error = ''
|
|
}
|
|
validateTimeout = undefined
|
|
}, 500)
|
|
} else {
|
|
error = ''
|
|
}
|
|
}
|
|
|
|
function validateName(meta: Meta): boolean {
|
|
if (meta.name == undefined || meta.name == '') {
|
|
error = 'choose a name'
|
|
return false
|
|
} else if (!/^[\w-]+(\/[\w-]+)*$/.test(meta.name)) {
|
|
error = 'This name is not valid.'
|
|
return false
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
|
|
$: {
|
|
if ($workspaceStore) {
|
|
loadGroups()
|
|
}
|
|
}
|
|
|
|
$: {
|
|
if (initialPath == undefined || initialPath == '') {
|
|
reset()
|
|
} else {
|
|
meta = pathToMeta(initialPath)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div>
|
|
<div class="flex flex-col sm:grid sm:grid-cols-4 sm:gap-4 pb-0 mb-1">
|
|
<label class="block">
|
|
<span class="text-gray-700 text-sm whitespace-nowrap">
|
|
Owner Kind <Tooltip>
|
|
<slot name="ownerToolkit" />
|
|
</Tooltip>
|
|
</span>
|
|
|
|
<select
|
|
bind:value={meta.ownerKind}
|
|
on:change={() => {
|
|
if (meta.ownerKind === 'group') {
|
|
meta.owner = 'all'
|
|
} else {
|
|
meta.owner = $userStore?.username ?? ''
|
|
}
|
|
}}
|
|
>
|
|
<option>user</option>
|
|
<option>group</option>
|
|
</select>
|
|
</label>
|
|
{#if meta.ownerKind === 'user'}
|
|
<label class="block">
|
|
<span class="text-sm text-gray-700">Owner</span>
|
|
<input
|
|
bind:value={meta.owner}
|
|
placeholder={$userStore?.username ?? ''}
|
|
disabled={!($userStore?.is_admin ?? false)}
|
|
/>
|
|
</label>
|
|
{:else}
|
|
<label class="block">
|
|
<span class="text-sm text-gray-700">Owner</span>
|
|
<select bind:value={meta.owner}>
|
|
{#each groups as g}
|
|
<option>{g.name}</option>
|
|
{/each}
|
|
</select>
|
|
</label>
|
|
{/if}
|
|
<label class="block col-span-2">
|
|
<span class="text-gray-700 text-sm">Name<span class="text-red-600 text-sm">*</span></span>
|
|
<input
|
|
bind:value={meta.name}
|
|
placeholder={namePlaceholder}
|
|
class={error === ''
|
|
? ''
|
|
: 'border border-red-700 bg-red-100 border-opacity-30 focus:border-red-700 focus:border-opacity-30 focus-visible:ring-red-700 focus-visible:ring-opacity-25 focus-visible:border-red-700'}
|
|
/>
|
|
</label>
|
|
</div>
|
|
<div class="pt-0 text-xs px-1 flex flex-col-reverse sm:grid sm:grid-cols-4 sm:gap-4 w-full">
|
|
<div class="col-span-2">Path: <span class="font-mono">{path}</span></div>
|
|
<div class="text-purple-500 text-2xs col-span-2">{error}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
input:disabled {
|
|
background: rgba(200, 200, 200, 0.267);
|
|
}
|
|
</style>
|