mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 00:01:55 +00:00
Migrating popup to popover
This commit is contained in:
@@ -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 <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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
+21
-17
@@ -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>
|
||||
|
||||
+12
-8
@@ -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
|
||||
|
||||
+55
-50
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user