Migrating popup to popover

This commit is contained in:
Guilhem
2025-02-13 21:13:52 +00:00
parent dec070458f
commit d93e3422cf
13 changed files with 442 additions and 416 deletions
+10 -8
View File
@@ -1,7 +1,8 @@
<script lang="ts">
import { Button, Popup } from './common'
import { Button } from './common'
import { Pen } from 'lucide-svelte'
import Tooltip from './Tooltip.svelte'
import Popover from './meltComponents/Popover.svelte'
import DefaultTagsInner from './DefaultTagsInner.svelte'
@@ -11,11 +12,8 @@
let placement: 'bottom-end' | 'top-end' = 'bottom-end'
</script>
<Popup
floatingConfig={{ strategy: 'absolute', placement: placement }}
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'absolute', placement: placement }}>
<svelte:fragment slot="trigger">
<Button color="dark" size="xs" nonCaptureEvent={true}>
<div class="flex flex-row gap-1 items-center"
><Pen size={14} /> Default tags&nbsp;<Tooltip light
@@ -25,5 +23,9 @@
>
</Button>
</svelte:fragment>
<DefaultTagsInner bind:defaultTagPerWorkspace bind:defaultTagWorkspaces />
</Popup>
<svelte:fragment slot="content">
<div class="p-4">
<DefaultTagsInner bind:defaultTagPerWorkspace bind:defaultTagWorkspaces />
</div>
</svelte:fragment>
</Popover>
@@ -2,7 +2,7 @@
import { Pencil } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import Button from './common/button/Button.svelte'
import Popup from './common/popup/Popup.svelte'
import Popover from './meltComponents/Popover.svelte'
import { offset, flip, shift } from 'svelte-floating-ui/dom'
import ChangeInstanceUsernameInner from './ChangeInstanceUsernameInner.svelte'
import { UserService } from '$lib/gen'
@@ -26,128 +26,124 @@
sendUserToast('Password must be at least 5 characters long', true)
return
}
await UserService.setPasswordForUser({user: email, requestBody:{ password }})
await UserService.setPasswordForUser({ user: email, requestBody: { password } })
sendUserToast(`Password updated for ${email}`)
}
async function saveLoginType() {
await UserService.setLoginTypeForUser({user: email, requestBody:{ login_type }})
await UserService.setLoginTypeForUser({ user: email, requestBody: { login_type } })
sendUserToast(`Login type updated for ${email}`)
dispatch('refresh')
}
</script>
<Popup
let:close
<Popover
floatingConfig={{
strategy: 'fixed',
placement: 'left-end',
middleware: [offset(8), flip(), shift()]
}}
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<Button nonCaptureEvent={true} size="xs" color="light" endIcon={{ icon: Pencil }}>Edit</Button>
</svelte:fragment>
<div class="flex flex-col gap-8 max-w-sm">
{#if automateUsernameCreation && username}
<ChangeInstanceUsernameInner {email} {username} on:renamed />
{/if}
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Name</div>
<div class="flex w-full">
<input
type="text"
bind:value
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
saveName()
close(null)
}
<svelte:fragment slot="content">
<div class="flex flex-col gap-8 max-w-sm p-4">
{#if automateUsernameCreation && username}
<ChangeInstanceUsernameInner {email} {username} on:renamed />
{/if}
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Name</div>
<div class="flex w-full">
<input
type="text"
bind:value
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
saveName()
}
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
on:click={() => {
saveName()
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
on:click={() => {
saveName()
close(null)
}}
>
Update name
</Button>
</label>
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Password</div>
<div class="flex w-full">
<input
type="password"
bind:value={password}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
savePassword()
close(null)
}
>
Update name
</Button>
</label>
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Password</div>
<div class="flex w-full">
<input
type="password"
bind:value={password}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
savePassword()
}
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
on:click={() => {
savePassword()
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save ID"
on:click={() => {
savePassword()
close(null)
}}
>
Update password
</Button>
</label>
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Login type</div>
<div class="text-xs text-secondary mb-2">
Must match exact SSO name, "password" or "saml". Examples: password, google, saml, microsoft
</div>
>
Update password
</Button>
</label>
<label class="block text-primary">
<div class="pb-2 text-sm font-semibold text-primary">Login type</div>
<div class="text-xs text-secondary mb-2">
Must match exact SSO name, "password" or "saml". Examples: password, google, saml,
microsoft
</div>
<div class="flex w-full">
<input
type="text"
bind:value={login_type}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
saveLoginType()
close(null)
}
<div class="flex w-full">
<input
type="text"
bind:value={login_type}
class="!w-auto grow"
on:click|stopPropagation={() => {}}
on:keydown|stopPropagation
on:keypress|stopPropagation={({ key }) => {
if (key === 'Enter') {
saveLoginType()
}
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save login type"
on:click={() => {
saveLoginType()
}}
/>
</div>
<Button
size="xs"
color="blue"
buttonType="button"
btnClasses="mt-2 "
aria-label="Save login type"
on:click={() => {
saveLoginType()
close(null)
}}
>
Update login type
</Button>
</label>
</div>
</Popup>
>
Update login type
</Button>
</label>
</div>
</svelte:fragment>
</Popover>
+45 -43
View File
@@ -3,7 +3,8 @@
import { createEventDispatcher } from 'svelte'
import { globalEmailInvite, superadmin, workspaceStore } from '$lib/stores'
import { UserService, WorkspaceService } from '$lib/gen'
import { Button, Popup } from './common'
import { Button } from './common'
import Popover from './meltComponents/Popover.svelte'
import { isCloudHosted } from '$lib/cloud'
import { goto } from '$lib/navigation'
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
@@ -64,53 +65,54 @@
let selected: 'operator' | 'developer' | 'admin' = 'developer'
</script>
<Popup floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}>
<svelte:fragment slot="trigger">
<Button color="dark" size="xs" nonCaptureEvent={true} startIcon={{ icon: MailPlus }}>
Invite
</Button>
</svelte:fragment>
<div class="flex flex-col gap-2">
<input
type="email"
on:keyup={handleKeyUp}
placeholder="email"
bind:value={email}
class="mr-4"
/>
<ToggleButtonGroup bind:selected>
<ToggleButton
value="operator"
size="sm"
label="Operator"
tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
<svelte:fragment slot="content">
<div class="flex flex-col gap-2 p-4">
<input
type="email"
on:keyup={handleKeyUp}
placeholder="email"
bind:value={email}
class="mr-4"
/>
<ToggleButtonGroup bind:selected>
<ToggleButton
value="operator"
size="sm"
label="Operator"
tooltip="An operator can only execute and view scripts/flows/apps from your workspace, and only those that he has visibility on."
/>
<ToggleButton
position="center"
value="developer"
size="sm"
label="Developer"
tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
/>
<ToggleButton
position="center"
value="developer"
size="sm"
label="Developer"
tooltip="A Developer can execute and view scripts/flows/apps, but they can also create new ones and edit those they are allowed to by their path (either u/ or Writer or Admin of their folder found at /f)."
/>
<ToggleButton
position="right"
value="admin"
<ToggleButton
position="right"
value="admin"
size="sm"
label="Admin"
tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
/>
</ToggleButtonGroup>
<Button
variant="contained"
color="blue"
size="sm"
label="Admin"
tooltip="An admin has full control over a specific Windmill workspace, including the ability to manage users, edit entities, and control permissions within the workspace."
/>
</ToggleButtonGroup>
<Button
variant="contained"
color="blue"
size="sm"
on:click={inviteUser}
disabled={email === undefined}
>
Invite
</Button>
</div>
</Popup>
on:click={inviteUser}
disabled={email === undefined}
>
Invite
</Button>
</div>
</svelte:fragment>
</Popover>
@@ -4,7 +4,8 @@
import { ResourceService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import IconedResourceType from './IconedResourceType.svelte'
import { Button, ClearableInput, Popup } from './common'
import { Button, ClearableInput } from './common'
import Popover from './meltComponents/Popover.svelte'
import { offset, flip, shift } from 'svelte-floating-ui/dom'
import Label from './Label.svelte'
import Tooltip from './Tooltip.svelte'
@@ -50,66 +51,65 @@
>
Clear
</Button>
<Popup
<Popover
floatingConfig={{
strategy: 'fixed',
placement: 'left-end',
middleware: [offset(8), flip(), shift()]
}}
containerClasses="border rounded-lg shadow-lg bg-surface p-4 w-[500px] h-[500px] "
let:close
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<Button nonCaptureEvent size="xs" color="dark">Select resource type</Button>
</svelte:fragment>
<svelte:fragment slot="content" let:close>
<div class="flex flex-col gap-2 h-full p-4">
<ClearableInput bind:value={search} placeholder="Search resource..." />
<div class="flex flex-col gap-2 h-full">
<ClearableInput bind:value={search} placeholder="Search resource..." />
<div class="overflow-y-scroll h-full">
<div
class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center overflow-x-hidden"
>
{#if nonePickable && search === ''}
{@const isPicked = value === undefined}
<Button
size="sm"
variant="border"
color={isPicked ? 'blue' : 'dark'}
btnClasses={isPicked ? '!border-2' : 'm-[1px]'}
disabled={notPickable}
on:click={() => {
onClick(undefined)
close()
}}
>
None
</Button>
{/if}
{#each filteredResources as r}
{@const isPicked = value === r}
<Button
size="sm"
variant="border"
color={isPicked ? 'blue' : 'light'}
btnClasses={isPicked ? '!border-2' : 'm-[1px]'}
disabled={notPickable}
on:click={() => {
onClick(r)
close()
}}
>
<IconedResourceType name={r} after={true} width="20px" height="20px" />
</Button>
{/each}
<div class="overflow-y-scroll h-full">
<div
class="grid sm:grid-cols-2 md:grid-cols-3 gap-x-2 gap-y-1 items-center overflow-x-hidden"
>
{#if nonePickable && search === ''}
{@const isPicked = value === undefined}
<Button
size="sm"
variant="border"
color={isPicked ? 'blue' : 'dark'}
btnClasses={isPicked ? '!border-2' : 'm-[1px]'}
disabled={notPickable}
on:click={() => {
onClick(undefined)
close(null)
}}
>
None
</Button>
{/if}
{#each filteredResources as r}
{@const isPicked = value === r}
<Button
size="sm"
variant="border"
color={isPicked ? 'blue' : 'light'}
btnClasses={isPicked ? '!border-2' : 'm-[1px]'}
disabled={notPickable}
on:click={() => {
onClick(r)
close(null)
}}
>
<IconedResourceType name={r} after={true} width="20px" height="20px" />
</Button>
{/each}
{#if filteredResources.length === 0 && search !== ''}
<div class="text-tertiary text-sm">No resources found</div>
{/if}
{#if filteredResources.length === 0 && search !== ''}
<div class="text-tertiary text-sm">No resources found</div>
{/if}
</div>
</div>
</div>
</div>
</Popup>
</svelte:fragment>
</Popover>
</div>
</svelte:fragment>
<div class="flex flex-row items-center w-full justify-between">
@@ -11,12 +11,12 @@
import AppSelect from '../../inputs/AppSelect.svelte'
import { twMerge } from 'tailwind-merge'
import { Popup } from '$lib/components/common'
import { Plug2 } from 'lucide-svelte'
import ComponentOutputViewer from '$lib/components/apps/editor/contextPanel/ComponentOutputViewer.svelte'
import { connectOutput } from '$lib/components/apps/editor/appUtils'
import RowWrapper from '../../layout/RowWrapper.svelte'
import type { ICellRendererParams } from 'ag-grid-community'
import Popover from '$lib/components/meltComponents/Popover.svelte'
export let p: ICellRendererParams<any>
export let id: string
@@ -124,34 +124,38 @@
{#if $connectingInput.opened}
<div class="absolute z-50 left-8 -top-[10px]">
<Popup
<Popover
floatingConfig={{
strategy: 'absolute',
placement: 'bottom-start'
}}
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<button
class="bg-red-500/70 border border-red-600 px-1 py-0.5"
title="Outputs"
aria-label="Open output"><Plug2 size={12} /></button
>
</svelte:fragment>
<ComponentOutputViewer
suffix="table"
on:select={({ detail }) => {
const tableId = action.id.split('_')[0]
<svelte:fragment slot="content">
<div class="p-4">
<ComponentOutputViewer
suffix="table"
on:select={({ detail }) => {
const tableId = action.id.split('_')[0]
connectOutput(
connectingInput,
action.type,
tableId,
`inputs.${action.id}[${rowIndex}].${detail}`
)
}}
componentId={action.id}
/>
</Popup>
connectOutput(
connectingInput,
action.type,
tableId,
`inputs.${action.id}[${rowIndex}].${detail}`
)
}}
componentId={action.id}
/>
</div>
</svelte:fragment>
</Popover>
</div>
{/if}
{/if}
@@ -39,12 +39,12 @@
import AppSelect from '../../inputs/AppSelect.svelte'
import RowWrapper from '../../layout/RowWrapper.svelte'
import ResolveStyle from '../../helpers/ResolveStyle.svelte'
import { Popup } from '$lib/components/common'
import ComponentOutputViewer from '$lib/components/apps/editor/contextPanel/ComponentOutputViewer.svelte'
import { EyeIcon, Plug2 } from 'lucide-svelte'
import AppCell from './AppCell.svelte'
import sum from 'hash-sum'
import RefreshButton from '$lib/components/apps/components/helpers/RefreshButton.svelte'
import Popover from '$lib/components/meltComponents/Popover.svelte'
export let id: string
export let componentInput: AppInput | undefined
@@ -553,31 +553,35 @@
{#if $connectingInput.opened}
<div class="absolute z-50 left-8 -top-[10px]">
<Popup
<Popover
floatingConfig={{
strategy: 'absolute',
placement: 'bottom-start'
}}
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<button
class="bg-red-500/70 border border-red-600 px-1 py-0.5"
title="Outputs"
aria-label="Open output"><Plug2 size={12} /></button
>
</svelte:fragment>
<ComponentOutputViewer
suffix="table"
on:select={({ detail }) =>
connectOutput(
connectingInput,
'buttoncomponent',
actionButton.id,
detail
)}
componentId={actionButton.id}
/>
</Popup>
<svelte:fragment slot="content">
<div class="p-4">
<ComponentOutputViewer
suffix="table"
on:select={({ detail }) =>
connectOutput(
connectingInput,
'buttoncomponent',
actionButton.id,
detail
)}
componentId={actionButton.id}
/>
</div>
</svelte:fragment>
</Popover>
</div>
{/if}
{/if}
@@ -3,8 +3,8 @@
import type { AppViewerContext } from '../types'
import { Anchor, ArrowDownFromLine, Bug, Network, Pen, Plug } from 'lucide-svelte'
import { createEventDispatcher, getContext } from 'svelte'
import Popover from '$lib/components/Popover.svelte'
import { Button, Popup } from '$lib/components/common'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import { Button } from '$lib/components/common'
import type { AppComponent } from './component'
import { twMerge } from 'tailwind-merge'
import { connectOutput } from './appUtils'
@@ -69,11 +69,8 @@
style="left: {id_width}px;"
data-connection-button
>
<Popup
floatingConfig={{ strategy: 'fixed', placement: 'bottom-start' }}
bind:popupHover={connectingPopupHover}
>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'fixed', placement: 'bottom-start' }}>
<svelte:fragment slot="trigger">
<AnimatedButton
animate={true}
baseRadius="9999px"
@@ -89,13 +86,17 @@
>
</AnimatedButton>
</svelte:fragment>
<ComponentOutputViewer
suffix="connect"
on:select={({ detail }) =>
connectOutput(connectingInput, component.type, component.id, detail)}
componentId={component.id}
/>
</Popup>
<svelte:fragment slot="content">
<div class="p-4">
<ComponentOutputViewer
suffix="connect"
on:select={({ detail }) =>
connectOutput(connectingInput, component.type, component.id, detail)}
componentId={component.id}
/>
</div>
</svelte:fragment>
</Popover>
</div>
{/if}
@@ -258,21 +259,25 @@
'text-red-500 px-1 text-2xs py-0.5 font-bold w-fit absolute border border-red-500 -bottom-1 shadow left-1/2 transform -translate-x-1/2 z-50 cursor-pointer'
)}
>
<Popover notClickable placement="bottom" popupClass="!bg-surface border w-96">
<Bug size={14} />
<span slot="text">
<div class="bg-surface">
<pre class=" whitespace-pre-wrap text-red-600 bg-surface border w-full p-4 text-xs mb-2"
>{error ?? ''}
</pre>
<Popover notClickable placement="bottom" class="!bg-surface border w-96">
<svelte:fragment slot="trigger">
<Bug size={14} />
</svelte:fragment>
<svelte:fragment slot="content">
<div class="p-4">
<div class="bg-surface">
<pre class="whitespace-pre-wrap text-red-600 bg-surface border w-full p-4 text-xs mb-2"
>{error ?? ''}
</pre>
</div>
<Button
color="red"
variant="border"
on:click={() => $openDebugRun?.($errorByComponent[component.id]?.id ?? '')}
>Open Debug Runs</Button
>
</div>
<Button
color="red"
variant="border"
on:click={() => $openDebugRun?.($errorByComponent[component.id]?.id ?? '')}
>Open Debug Runs</Button
>
</span>
</svelte:fragment>
</Popover>
</span>
{/if}
@@ -1,7 +1,6 @@
<script lang="ts">
import Button from '$lib/components/common/button/Button.svelte'
import { Popup } from '$lib/components/common'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import { Pen } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
@@ -21,29 +20,30 @@
}
</script>
<Popup
floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
let:close
>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}>
<svelte:fragment slot="trigger">
<Button color="light" size="xs2" nonCaptureEvent={true}>
<div class="flex flex-row gap-1 items-center">
<Pen size={16} />
</div>
</Button>
</svelte:fragment>
<div class="flex flex-col w-80 gap-2">
<div class="leading-6 font-semibold text-xs">Edit {kind} name</div>
<div class="flex flex-row gap-2">
<input on:keydown={onkeydown} bind:value={editedName} />
<Button
color="dark"
size="xs"
on:click={() => dispatch('update', { path: row.path, name: editedName }) && close(null)}
>
Update
</Button>
<svelte:fragment slot="content" let:close>
<div class="flex flex-col w-80 gap-2 p-4">
<div class="leading-6 font-semibold text-xs">Edit {kind} name</div>
<div class="flex flex-row gap-2">
<input on:keydown={onkeydown} bind:value={editedName} />
<Button
color="dark"
size="xs"
on:click={() => {
dispatch('update', { path: row.path, name: editedName })
close()
}}
>
Update
</Button>
</div>
</div>
</div>
</Popup>
</svelte:fragment>
</Popover>
@@ -2,8 +2,7 @@
import { updateTheme } from './themeUtils'
import { workspaceStore } from '$lib/stores'
import Button from '$lib/components/common/button/Button.svelte'
import { Popup } from '$lib/components/common'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import { Pen } from 'lucide-svelte'
import { createEventDispatcher } from 'svelte'
import { sendUserToast } from '$lib/toast'
@@ -18,40 +17,38 @@
const dispatch = createEventDispatcher()
</script>
<Popup
floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
let:close
>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}>
<svelte:fragment slot="trigger">
<Button color="light" size="xs2" nonCaptureEvent={true}>
<div class="flex flex-row gap-1 items-center">
<Pen size={16} />
</div>
</Button>
</svelte:fragment>
<div class="flex flex-col w-80 gap-2">
<div class="leading-6 font-semibold text-xs">Edit theme name</div>
<div class="flex flex-row gap-2">
<input bind:value={editedName} />
<Button
color="dark"
size="xs"
on:click={async () => {
if (!$workspaceStore) return
await updateTheme($workspaceStore, row.path, {
value: {
...row,
name: editedName
}
})
dispatch('reloadThemes')
close(null)
sendUserToast('Theme name updated:\n' + editedName)
}}
>
Update
</Button>
<svelte:fragment slot="content" let:close>
<div class="flex flex-col w-80 gap-2 p-4">
<div class="leading-6 font-semibold text-xs">Edit theme name</div>
<div class="flex flex-row gap-2">
<input bind:value={editedName} />
<Button
color="dark"
size="xs"
on:click={async () => {
if (!$workspaceStore) return
await updateTheme($workspaceStore, row.path, {
value: {
...row,
name: editedName
}
})
dispatch('reloadThemes')
close()
sendUserToast('Theme name updated:\n' + editedName)
}}
>
Update
</Button>
</div>
</div>
</div>
</Popup>
</svelte:fragment>
</Popover>
@@ -4,7 +4,7 @@
import { Pencil } from 'lucide-svelte'
import { createEventDispatcher, getContext } from 'svelte'
import IdEditorInput from '$lib/components/IdEditorInput.svelte'
import { Popup } from '$lib/components/common'
import Popover from '$lib/components/meltComponents/Popover.svelte'
const { app, selectedComponent } = getContext<AppViewerContext>('AppViewerContext')
@@ -15,8 +15,8 @@
$: reservedIds = allItems($app.grid, $app.subgrids).map((item) => item.id)
</script>
<Popup let:close floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}>
<svelte:fragment slot="button">
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}>
<svelte:fragment slot="trigger">
<button
on:click={() => {
$selectedComponent = [id]
@@ -28,13 +28,17 @@
<Pencil size={14} />
</button>
</svelte:fragment>
<IdEditorInput
initialId={id}
on:close={() => close(null)}
on:save={(e) => {
dispatch('save', e.detail)
close(null)
}}
{reservedIds}
/>
</Popup>
<svelte:fragment slot="content" let:close>
<div class="p-4">
<IdEditorInput
initialId={id}
on:close={() => close()}
on:save={(e) => {
dispatch('save', e.detail)
close()
}}
{reservedIds}
/>
</div>
</svelte:fragment>
</Popover>
@@ -1,13 +1,14 @@
<script lang="ts">
import Toggle from '$lib/components/Toggle.svelte'
import { Button, Popup, SecondsInput } from '$lib/components/common'
import { autoPlacement } from '@floating-ui/core'
import { Button, SecondsInput } from '$lib/components/common'
import { Database } from 'lucide-svelte'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import { autoPlacement } from '@floating-ui/core'
export let cache_ttl: number | undefined
</script>
<Popup
<Popover
floatingConfig={{
middleware: [
autoPlacement({
@@ -16,7 +17,7 @@
]
}}
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<Button
nonCaptureEvent={true}
btnClasses={Boolean(cache_ttl)
@@ -30,28 +31,30 @@
title="Cache settings"
/>
</svelte:fragment>
<div class="block text-primary">
<Toggle
checked={Boolean(cache_ttl)}
on:change={() => {
if (cache_ttl != undefined) {
cache_ttl = undefined
} else {
cache_ttl = 600
}
}}
options={{
right: 'Cache the results for each possible inputs'
}}
/>
<div class="mb-4">
<span class="text-xs font-bold">How long to keep cache valid</span>
<svelte:fragment slot="content">
<div class="block text-primary p-4">
<Toggle
checked={Boolean(cache_ttl)}
on:change={() => {
if (cache_ttl != undefined) {
cache_ttl = undefined
} else {
cache_ttl = 600
}
}}
options={{
right: 'Cache the results for each possible inputs'
}}
/>
<div class="mb-4">
<span class="text-xs font-bold">How long to keep cache valid</span>
{#if cache_ttl}
<SecondsInput bind:seconds={cache_ttl} />
{:else}
<SecondsInput disabled />
{/if}
{#if cache_ttl}
<SecondsInput bind:seconds={cache_ttl} />
{:else}
<SecondsInput disabled />
{/if}
</div>
</div>
</div>
</Popup>
</svelte:fragment>
</Popover>
@@ -1,5 +1,5 @@
<script lang="ts">
import { Button, Drawer, DrawerContent, Popup } from '$lib/components/common'
import { Button, Drawer, DrawerContent } from '$lib/components/common'
import { base } from '$lib/base'
import FlowModuleScript from '$lib/components/flows/content/FlowModuleScript.svelte'
import FlowPathViewer from '$lib/components/flows/content/FlowPathViewer.svelte'
@@ -23,6 +23,7 @@
import { sendUserToast } from '$lib/toast'
import { autoPlacement } from '@floating-ui/core'
import { ExternalLink, Eye, GitFork, Pen, RefreshCw, Trash } from 'lucide-svelte'
import Popover from '$lib/components/meltComponents/Popover.svelte'
export let runnable: RunnableByPath
export let fields: Record<string, StaticAppInput | ConnectedAppInput | RowAppInput | UserAppInput>
@@ -180,7 +181,7 @@
Fork
</Button>
{/if}
<Popup
<Popover
floatingConfig={{
middleware: [
autoPlacement({
@@ -196,7 +197,7 @@
]
}}
>
<svelte:fragment slot="button">
<svelte:fragment slot="trigger">
<Button
nonCaptureEvent={true}
btnClasses={'bg-surface text-primay hover:bg-hover'}
@@ -205,11 +206,14 @@
size="xs">Cache</Button
>
</svelte:fragment>
<div class="block text-primary">
Since this is a reference to a workspace {runnable.runType}, set the cache in the {runnable.runType}
settings directly by editing it. The cache will be shared by any app or flow that uses this {runnable.runType}.
</div>
</Popup>
<svelte:fragment slot="content">
<div class="block text-primary p-4">
Since this is a reference to a workspace {runnable.runType}, set the cache in the {runnable.runType}
settings directly by editing it. The cache will be shared by any app or flow that uses this
{runnable.runType}.
</div>
</svelte:fragment>
</Popover>
<input
on:keydown|stopPropagation
@@ -1,8 +1,9 @@
<script lang="ts">
import { Loader2 } from 'lucide-svelte'
import { ClearableInput, Popup } from '../../../../common'
import { ClearableInput } from '../../../../common'
import { AllIcons } from './icons'
import type { ComputeConfig } from 'svelte-floating-ui'
import Popover from '$lib/components/meltComponents/Popover.svelte'
export let value: string | undefined = ''
@@ -43,8 +44,8 @@
export let shouldUsePortal: boolean = true
</script>
<Popup let:close {floatingConfig} {shouldUsePortal}>
<svelte:fragment slot="button">
<Popover {floatingConfig} {shouldUsePortal}>
<svelte:fragment slot="trigger">
<div class="relative">
<ClearableInput
readonly
@@ -60,52 +61,56 @@
{/if}
</div>
</svelte:fragment>
{#if !loading}
{#if filteredItems}
<div class="w-72">
<input
on:keydown={(event) => {
if (!['ArrowDown', 'ArrowUp'].includes(event.key)) {
event.stopPropagation()
}
}}
bind:value={search}
type="text"
placeholder="Search"
class="col-span-4 mb-2"
/>
<div class="grid gap-1 grid-cols-4 max-h-[300px] overflow-auto">
{#each filteredItems as label}
<button
type="button"
title={label}
on:click={() => {
select(label)
close(null)
<svelte:fragment slot="content" let:close>
<div class="p-4">
{#if !loading}
{#if filteredItems}
<div class="w-72">
<input
on:keydown={(event) => {
if (!['ArrowDown', 'ArrowUp'].includes(event.key)) {
event.stopPropagation()
}
}}
class="w-full center-center flex-col font-normal p-1
hover:bg-gray-100 focus:bg-gray-100 rounded duration-200 dark:hover:bg-frost-900 dark:focus:bg-frost-900
{label === value ? 'text-blue-600 bg-blue-50 pointer-events-none' : ''}"
>
<!-- svelte-ignore a11y-missing-attribute -->
<img
class="dark:invert"
loading="lazy"
src="https://cdn.jsdelivr.net/npm/lucide-static@0.367.0/icons/{label}.svg"
/>
<span class="inline-block w-full text-[10px] ellipsize pt-0.5">
{label}
</span>
</button>
{:else}
<div class="col-span-4 text-center text-secondary text-sm p-2">
No icons match your search
bind:value={search}
type="text"
placeholder="Search"
class="col-span-4 mb-2"
/>
<div class="grid gap-1 grid-cols-4 max-h-[300px] overflow-auto">
{#each filteredItems as label}
<button
type="button"
title={label}
on:click={() => {
select(label)
close()
}}
class="w-full center-center flex-col font-normal p-1
hover:bg-gray-100 focus:bg-gray-100 rounded duration-200 dark:hover:bg-frost-900 dark:focus:bg-frost-900
{label === value ? 'text-blue-600 bg-blue-50 pointer-events-none' : ''}"
>
<!-- svelte-ignore a11y-missing-attribute -->
<img
class="dark:invert"
loading="lazy"
src="https://cdn.jsdelivr.net/npm/lucide-static@0.367.0/icons/{label}.svg"
/>
<span class="inline-block w-full text-[10px] ellipsize pt-0.5">
{label}
</span>
</button>
{:else}
<div class="col-span-4 text-center text-secondary text-sm p-2">
No icons match your search
</div>
{/each}
</div>
{/each}
</div>
</div>
{:else}
<div class="text-center text-sm text-secondary p-2"> Couldn't load options </div>
{/if}
{/if}
</Popup>
</div>
{:else}
<div class="text-center text-sm text-secondary p-2"> Couldn't load options </div>
{/if}
{/if}
</div>
</svelte:fragment>
</Popover>