mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-24 16:01:42 +00:00
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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user