fix(app): consolidate add project action (#34086)
This commit is contained in:
@@ -69,12 +69,14 @@ export function createPromptProjectController(input: {
|
|||||||
if (servers().length <= 1) {
|
if (servers().length <= 1) {
|
||||||
return [...projects().map(projectKey), actionKey(servers()[0]?.key)]
|
return [...projects().map(projectKey), actionKey(servers()[0]?.key)]
|
||||||
}
|
}
|
||||||
return servers().flatMap((server) => [
|
return [
|
||||||
...projects()
|
...servers().flatMap((server) =>
|
||||||
|
projects()
|
||||||
.filter((project) => project.server?.key === server!.key)
|
.filter((project) => project.server?.key === server!.key)
|
||||||
.map(projectKey),
|
.map(projectKey),
|
||||||
actionKey(server!.key),
|
),
|
||||||
])
|
actionKey(),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
const initialActive = () => {
|
const initialActive = () => {
|
||||||
const selectedKey = selected() ? projectKey(selected()!) : undefined
|
const selectedKey = selected() ? projectKey(selected()!) : undefined
|
||||||
@@ -130,7 +132,10 @@ export function createPromptProjectController(input: {
|
|||||||
const first = input
|
const first = input
|
||||||
.controls()
|
.controls()
|
||||||
.available.find((project) => !search || displayName(project).toLowerCase().includes(search))
|
.available.find((project) => !search || displayName(project).toLowerCase().includes(search))
|
||||||
setStore({ search: value, active: first ? projectKey(first) : actionKey(servers()[0]?.key) })
|
setStore({
|
||||||
|
search: value,
|
||||||
|
active: first ? projectKey(first) : actionKey(servers().length > 1 ? undefined : servers()[0]?.key),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
clearSearch() {
|
clearSearch() {
|
||||||
setStore({ search: "", active: initialActive() })
|
setStore({ search: "", active: initialActive() })
|
||||||
@@ -156,6 +161,9 @@ export function createPromptProjectController(input: {
|
|||||||
? decodeURIComponent(store.active.slice(actionPrefix.length)) || undefined
|
? decodeURIComponent(store.active.slice(actionPrefix.length)) || undefined
|
||||||
: undefined
|
: undefined
|
||||||
},
|
},
|
||||||
|
activeAction() {
|
||||||
|
return store.active.startsWith(actionPrefix)
|
||||||
|
},
|
||||||
setSearchRef(el: HTMLInputElement) {
|
setSearchRef(el: HTMLInputElement) {
|
||||||
searchRef = el
|
searchRef = el
|
||||||
},
|
},
|
||||||
@@ -204,6 +212,12 @@ export function PromptProjectSelector(props: {
|
|||||||
selectProject(project)
|
selectProject(project)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (props.controller.activeAction() && props.controller.servers().length > 1) {
|
||||||
|
const item = activeItem()
|
||||||
|
item?.focus()
|
||||||
|
item?.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowRight", bubbles: true }))
|
||||||
|
return
|
||||||
|
}
|
||||||
selectAction(props.controller.activeServer())
|
selectAction(props.controller.activeServer())
|
||||||
}
|
}
|
||||||
const moveActive = (delta: number) => {
|
const moveActive = (delta: number) => {
|
||||||
@@ -320,7 +334,13 @@ export function PromptProjectSelector(props: {
|
|||||||
</DropdownMenu.RadioGroup>
|
</DropdownMenu.RadioGroup>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<For each={props.controller.servers()}>
|
<For
|
||||||
|
each={props.controller
|
||||||
|
.servers()
|
||||||
|
.filter((server) =>
|
||||||
|
props.controller.projects().some((project) => project.server?.key === server!.key),
|
||||||
|
)}
|
||||||
|
>
|
||||||
{(server) => (
|
{(server) => (
|
||||||
<div>
|
<div>
|
||||||
<div class="flex h-7 select-none items-center pl-1.5 pr-3 text-[11px] font-[530] leading-none tracking-[0.05px] text-v2-text-text-faint">
|
<div class="flex h-7 select-none items-center pl-1.5 pr-3 text-[11px] font-[530] leading-none tracking-[0.05px] text-v2-text-text-faint">
|
||||||
@@ -333,22 +353,49 @@ export function PromptProjectSelector(props: {
|
|||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</DropdownMenu.RadioGroup>
|
</DropdownMenu.RadioGroup>
|
||||||
<ProjectAction server={server!.key} controller={props.controller} onSelect={selectAction} />
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
<Show when={props.controller.servers().length <= 1}>
|
|
||||||
<div class="h-px bg-v2-border-border-muted" />
|
<div class="h-px bg-v2-border-border-muted" />
|
||||||
<div class="flex flex-col p-0.5">
|
<div class="flex flex-col p-0.5">
|
||||||
|
<Show
|
||||||
|
when={props.controller.servers().length > 1}
|
||||||
|
fallback={
|
||||||
<ProjectAction
|
<ProjectAction
|
||||||
server={props.controller.servers()[0]?.key}
|
server={props.controller.servers()[0]?.key}
|
||||||
controller={props.controller}
|
controller={props.controller}
|
||||||
onSelect={selectAction}
|
onSelect={selectAction}
|
||||||
/>
|
/>
|
||||||
</div>
|
}
|
||||||
|
>
|
||||||
|
<DropdownMenu.Sub>
|
||||||
|
<DropdownMenu.SubTrigger
|
||||||
|
id={props.controller.actionKey()}
|
||||||
|
data-option-key={props.controller.actionKey()}
|
||||||
|
class={projectActionClass}
|
||||||
|
classList={{
|
||||||
|
"!bg-v2-overlay-simple-overlay-hover": props.controller.active() === props.controller.actionKey(),
|
||||||
|
}}
|
||||||
|
onMouseEnter={() => props.controller.setActive(props.controller.actionKey())}
|
||||||
|
>
|
||||||
|
<Icon name="plus" size="small" />
|
||||||
|
<span data-slot="dropdown-menu-item-label" class="min-w-0 flex-1 truncate leading-5">
|
||||||
|
{props.controller.labels.add()}
|
||||||
|
</span>
|
||||||
|
<Icon name="chevron-right" size="small" class="shrink-0 text-v2-icon-icon-muted" />
|
||||||
|
</DropdownMenu.SubTrigger>
|
||||||
|
<DropdownMenu.Portal>
|
||||||
|
<DropdownMenu.SubContent class="min-w-[180px] overflow-hidden rounded-md border-0 bg-v2-background-bg-layer-01 p-0.5 shadow-[var(--v2-elevation-floating)] focus:outline-none">
|
||||||
|
<For each={props.controller.servers()}>
|
||||||
|
{(server) => <ServerAction server={server!} onSelect={selectAction} />}
|
||||||
|
</For>
|
||||||
|
</DropdownMenu.SubContent>
|
||||||
|
</DropdownMenu.Portal>
|
||||||
|
</DropdownMenu.Sub>
|
||||||
</Show>
|
</Show>
|
||||||
|
</div>
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Portal>
|
</DropdownMenu.Portal>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@@ -457,6 +504,9 @@ function ProjectItem(props: {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const projectActionClass =
|
||||||
|
"h-7 gap-2 rounded-sm px-3 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-base [font-family:var(--v2-font-family-sans)] data-[highlighted]:!bg-v2-overlay-simple-overlay-hover"
|
||||||
|
|
||||||
function ProjectAction(props: {
|
function ProjectAction(props: {
|
||||||
server?: string
|
server?: string
|
||||||
controller: PromptProjectController
|
controller: PromptProjectController
|
||||||
@@ -491,3 +541,11 @@ function ProjectAction(props: {
|
|||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ServerAction(props: { server: { key: string; name: string }; onSelect: (server: string) => void }) {
|
||||||
|
return (
|
||||||
|
<DropdownMenu.Item class={projectActionClass} onSelect={() => props.onSelect(props.server.key)}>
|
||||||
|
<DropdownMenu.ItemLabel class="min-w-0 flex-1 truncate leading-5">{props.server.name}</DropdownMenu.ItemLabel>
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user