Files
windmill/frontend/src/lib/components/GitRepoPopoverPicker.svelte
T
6186a0645d feat: edit variables, resources and triggers in their own session tab (#11206)
* feat: edit variables, resources and triggers in their own session tab

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: take a trigger's flow kind from its config and name the written trigger

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* refactor: one operating-workspace context for editors acting on a session's workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: reload page item tabs only in sessions acting on the tool's workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: resolve open in workspace for every preview tab kind in one place

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: guard every component under a session editor against the navigation workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: show a page item tab whose item is gone instead of mounting its editor

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: follow a saved page item in the tab's own workspace and restore in-frame rows

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat: close a page item tab from its editor header

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: judge trigger permissions by the user acting in the session workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: judge every session-editor permission by the user acting in that workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: keep session permissions reactive to the acting role and restore tabs as last seen

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix: default Path's owner controls to the user acting in its workspace

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
2026-09-19 23:29:14 +02:00

99 lines
2.7 KiB
Svelte

<script lang="ts">
import { ResourceService } from '$lib/gen'
import { Popover } from './meltComponents'
import { GitBranch, Loader2 } from 'lucide-svelte'
import { createEventDispatcher, untrack } from 'svelte'
import { useOperatingWorkspace } from '$lib/components/operatingWorkspace.svelte'
const operatingWorkspace = useOperatingWorkspace()
interface Props {
isOpen?: boolean
children?: import('svelte').Snippet
}
let { isOpen = $bindable(false), children }: Props = $props()
const dispatch = createEventDispatcher<{
selected: { resourcePath: string }
}>()
let loading = $state(false)
let gitRepoResources = $state<{ path: string; description?: string }[]>([])
async function loadGitRepoResources() {
if (!$operatingWorkspace || loading) return
loading = true
try {
const resources = await ResourceService.listResource({
workspace: $operatingWorkspace,
resourceType: 'git_repository'
})
gitRepoResources = resources
} catch (error) {
console.error('Failed to load git repository resources:', error)
gitRepoResources = []
} finally {
loading = false
}
}
$effect(() => {
if (isOpen && $operatingWorkspace) {
untrack(() => loadGitRepoResources())
}
})
function handleSelect(resourcePath: string) {
dispatch('selected', { resourcePath })
isOpen = false
}
</script>
<Popover
floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}
usePointerDownOutside
closeOnOtherPopoverOpen
bind:isOpen
escapeBehavior="ignore"
>
{#snippet trigger()}
{@render children?.()}
{/snippet}
{#snippet content()}
<div class="w-64 max-h-72 overflow-y-auto">
{#if loading}
<div class="flex items-center gap-2 p-3">
<Loader2 size={16} class="animate-spin" />
<span class="text-sm text-secondary">Loading...</span>
</div>
{:else if gitRepoResources.length === 0}
<div class="p-4 text-center">
<GitBranch size={20} class="mx-auto mb-2 text-primary" />
<p class="text-sm text-secondary mb-1">No git repositories found</p>
<p class="text-xs text-primary">Create a git repository resource first</p>
</div>
{:else}
<div class="py-1">
{#each gitRepoResources as resource}
<button
class="w-full text-left px-3 py-2 hover:bg-surface-hover text-sm flex items-center gap-2 transition-colors"
onclick={() => handleSelect(resource.path)}
>
<GitBranch size={14} class="text-primary flex-shrink-0" />
<div class="flex-1 min-w-0">
<div class="font-medium text-primary truncate">{resource.path}</div>
{#if resource.description}
<div class="text-xs text-primary truncate">{resource.description}</div>
{/if}
</div>
</button>
{/each}
</div>
{/if}
</div>
{/snippet}
</Popover>