feat: improve FolderPicker with edit icon pattern (#7995)

* feat: replace native select with custom Select in FolderPicker

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: update ee-repo-ref to 592848d59ca2304926fb2bd85d000668a7f46a77

This commit updates the EE repository reference after PR #420 was merged in windmill-ee-private.

Previous ee-repo-ref: 931813b75b8260faa13ddc07f36a11607b7e3bf6

New ee-repo-ref: 592848d59ca2304926fb2bd85d000668a7f46a77

Automated by sync-ee-ref workflow.

* nit

* fix(frontend): edit button in folder picker dropdown should not select the item

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restore ee-repo-ref.txt to match main

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(frontend): clean up FolderPicker review nits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update frontend/src/lib/components/FolderPicker.svelte

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
This commit is contained in:
Guilhem
2026-02-18 11:06:04 +00:00
committed by GitHub
parent 86ed35056c
commit fecebb69b2
+56 -17
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import { FolderService } from '$lib/gen'
import { workspaceStore, userStore } from '$lib/stores'
import { Eye, PlusIcon } from 'lucide-svelte'
import { Pen, PlusIcon } from 'lucide-svelte'
import { Button, Drawer, DrawerContent } from './common'
import FolderEditor from './FolderEditor.svelte'
import Select from './select/Select.svelte'
@@ -23,6 +23,7 @@
let folderCreated: string | undefined = $state(undefined)
let creating: boolean = $state(false)
let loadingFolders: boolean = $state(true)
let editingFolder: string = $state('')
type Props = {
folderName: string
@@ -42,6 +43,8 @@
drawerOffset = 0
}: Props = $props()
let hovering = $state(false)
async function loadFolders(): Promise<void> {
loadingFolders = true
try {
@@ -93,11 +96,16 @@
requestBody: { name: newFolderName }
})
folderCreated = newFolderName
if ($userStore) {
$userStore.folders = [...($userStore.folders ?? []), newFolderName]
}
await loadFolders()
folderName = newFolderName
// Writing $userStore.folders = [...] would call userStore.set(),
// which re-triggers Path.svelte's $effect.pre and calls initPath()/reset(),
// switching the owner toggle from "Folder" back to "User".
if ($userStore) {
if (!$userStore.folders) $userStore.folders = []
$userStore.folders.push(newFolderName)
}
} catch (e) {
sendUserToast(`Could not create folder: ${e}`, true)
} finally {
@@ -172,7 +180,7 @@
variant="accent"
disabled={!newFolderName || !!nameError || creating}
loading={creating}
on:click={addFolder}
onClick={addFolder}
>
Create
</Button>
@@ -182,13 +190,20 @@
</Drawer>
<Drawer bind:this={viewFolder} offset={drawerOffset}>
<DrawerContent title="Folder {folderName}" on:close={viewFolder.closeDrawer}>
<FolderEditor name={folderName ?? ''} />
<DrawerContent title="Folder {editingFolder}" on:close={viewFolder.closeDrawer}>
<FolderEditor name={editingFolder} />
</DrawerContent>
</Drawer>
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div class="flex flex-row items-center gap-1 w-full" onkeydown={handleSelectKeydown}>
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class="flex flex-row w-full items-center relative"
role="group"
onkeydown={handleSelectKeydown}
onmouseenter={() => (hovering = true)}
onmouseleave={() => (hovering = false)}
>
<Select
bind:value={folderName}
bind:filterText
@@ -198,7 +213,24 @@
loading={loadingFolders}
{size}
placeholder="Select folder"
class="grow min-w-0"
>
{#snippet endSnippet({ item, close })}
<Button
disabled={disabled || disableEditing}
variant="subtle"
unifiedSize="xs"
wrapperClasses="-mr-2 pl-1 -my-2"
btnClasses="hover:bg-surface-tertiary"
onClick={() => {
editingFolder = item.value ?? ''
viewFolder?.openDrawer()
close()
}}
startIcon={{ icon: Pen }}
iconOnly
/>
{/snippet}
{#snippet bottomSnippet({ close })}
<button
class="sticky py-2 px-4 w-full text-left text-xs font-medium hover:bg-surface-hover flex items-center justify-center gap-2 border-t border-border-light {noMatchingItems
@@ -214,13 +246,20 @@
</button>
{/snippet}
</Select>
<Button
title="View folder"
variant="subtle"
unifiedSize={size}
disabled={!folderName || folderName == ''}
on:click={viewFolder.openDrawer}
iconOnly
startIcon={{ icon: Eye }}
/>
{#if folderName && hovering && !loadingFolders && !disabled && !disableEditing}
<div class="absolute right-2 z-20">
<Button
variant="subtle"
unifiedSize="xs"
wrapperClasses="pl-1"
btnClasses="hover:bg-surface-tertiary"
onClick={() => {
editingFolder = folderName
viewFolder?.openDrawer()
}}
startIcon={{ icon: Pen }}
iconOnly
/>
</div>
{/if}
</div>