mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-20 16:03:21 +00:00
replace popup with melt popover
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Button, Popup } from './common'
|
||||
import { Button } from './common'
|
||||
import { Pen } from 'lucide-svelte'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
|
||||
import Tooltip from './Tooltip.svelte'
|
||||
import AssignableTagsInner from './AssignableTagsInner.svelte'
|
||||
@@ -11,12 +12,13 @@
|
||||
export let showWorkspaceRestriction = false
|
||||
</script>
|
||||
|
||||
<Popup
|
||||
<Popover
|
||||
floatingConfig={{ strategy: 'absolute', placement: placement }}
|
||||
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
|
||||
{disabled}
|
||||
closeButton
|
||||
usePointerDownOutside
|
||||
>
|
||||
<svelte:fragment slot="button">
|
||||
<svelte:fragment slot="trigger">
|
||||
<Button {color} size="xs" nonCaptureEvent={true} {disabled}>
|
||||
<div class="flex flex-row gap-1 items-center"
|
||||
><Pen size={14} /> Custom tags <Tooltip light
|
||||
@@ -28,5 +30,7 @@
|
||||
>
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<AssignableTagsInner {showWorkspaceRestriction} on:refresh />
|
||||
</Popup>
|
||||
<svelte:fragment slot="content">
|
||||
<AssignableTagsInner {showWorkspaceRestriction} on:refresh />
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
loadCustomTags()
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col w-72 p-2 gap-2">
|
||||
<div class="flex flex-col w-72 p-4 gap-2">
|
||||
{#if customTags == undefined}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:else}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Button, Popup } from './common'
|
||||
import { Button } from './common'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
import { autoPlacement } from '@floating-ui/core'
|
||||
import ChangeInstanceUsernameInner from './ChangeInstanceUsernameInner.svelte'
|
||||
|
||||
@@ -8,7 +9,7 @@
|
||||
export let isConflict = false
|
||||
</script>
|
||||
|
||||
<Popup
|
||||
<Popover
|
||||
floatingConfig={{
|
||||
middleware: [
|
||||
autoPlacement({
|
||||
@@ -16,19 +17,20 @@
|
||||
})
|
||||
]
|
||||
}}
|
||||
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
|
||||
let:close
|
||||
closeButton
|
||||
>
|
||||
<svelte:fragment slot="button">
|
||||
<svelte:fragment slot="trigger">
|
||||
<Button color={isConflict ? 'red' : 'light'} size="xs" spacingSize="xs2" nonCaptureEvent={true}
|
||||
>{isConflict ? 'Fix username conflict' : 'Change username'}</Button
|
||||
>
|
||||
</svelte:fragment>
|
||||
<ChangeInstanceUsernameInner
|
||||
{email}
|
||||
{username}
|
||||
{isConflict}
|
||||
on:close={() => close(null)}
|
||||
on:renamed
|
||||
/>
|
||||
</Popup>
|
||||
<svelte:fragment slot="content">
|
||||
<ChangeInstanceUsernameInner
|
||||
{email}
|
||||
{username}
|
||||
{isConflict}
|
||||
on:close={() => close()}
|
||||
on:renamed
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
|
||||
@@ -71,11 +71,9 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col max-w-2xl p-2">
|
||||
{#if isConflict}
|
||||
<span class="text-sm mb-2 leading-6 font-semibold"
|
||||
>Fix username conflict</span
|
||||
>
|
||||
<div class="flex flex-col max-w-2xl p-4">
|
||||
{#if isConflict}
|
||||
<span class="text-sm mb-2 leading-6 font-semibold">Fix username conflict</span>
|
||||
{/if}
|
||||
|
||||
<span class="text-sm font-semibold mb-1 leading-6"
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
<script lang="ts">
|
||||
import Section from './Section.svelte'
|
||||
import { Button, Popup } from './common'
|
||||
import { Button } from './common'
|
||||
import { Clock } from 'lucide-svelte'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
</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' }} closeButton>
|
||||
<svelte:fragment slot="trigger">
|
||||
<Button color="dark" size="xs" nonCaptureEvent={true} startIcon={{ icon: Clock }}>
|
||||
Use simplified builder
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<Section label="CRON Builder">
|
||||
<div class="flex flex-col w-72">
|
||||
<slot {close} />
|
||||
</div>
|
||||
</Section>
|
||||
</Popup>
|
||||
<svelte:fragment slot="content" let:close>
|
||||
<Section label="CRON Builder" wrapperClass="p-4">
|
||||
<div class="flex flex-col w-72">
|
||||
<slot {close} />
|
||||
</div>
|
||||
</Section>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
import { Settings } from 'lucide-svelte'
|
||||
import FormatOnSave from './FormatOnSave.svelte'
|
||||
import VimMode from './VimMode.svelte'
|
||||
import { Button, Popup } from './common'
|
||||
import { Button } from './common'
|
||||
import CodeCompletionStatus from './copilot/CodeCompletionStatus.svelte'
|
||||
import type { EditorBarUi } from './custom_ui'
|
||||
import Popover from './meltComponents/Popover.svelte'
|
||||
|
||||
export let customUi: EditorBarUi = {}
|
||||
</script>
|
||||
|
||||
{#if customUi?.autoformatting != false || customUi?.vimMode != false || customUi?.aiCompletion != false}
|
||||
<Popup
|
||||
floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
|
||||
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
|
||||
>
|
||||
<svelte:fragment slot="button">
|
||||
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }} usePointerDownOutside>
|
||||
<svelte:fragment slot="trigger">
|
||||
<Button
|
||||
btnClasses="text-tertiary"
|
||||
color="light"
|
||||
@@ -26,22 +24,24 @@
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="flex flex-col gap-y-2">
|
||||
{#if customUi?.autoformatting != false}
|
||||
<div>
|
||||
<FormatOnSave />
|
||||
</div>
|
||||
{/if}
|
||||
{#if customUi?.vimMode != false}
|
||||
<div>
|
||||
<VimMode />
|
||||
</div>
|
||||
{/if}
|
||||
{#if customUi?.aiCompletion != false}
|
||||
<div>
|
||||
<CodeCompletionStatus />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Popup>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="flex flex-col gap-y-2 p-4">
|
||||
{#if customUi?.autoformatting != false}
|
||||
<div>
|
||||
<FormatOnSave />
|
||||
</div>
|
||||
{/if}
|
||||
{#if customUi?.vimMode != false}
|
||||
<div>
|
||||
<VimMode />
|
||||
</div>
|
||||
{/if}
|
||||
{#if customUi?.aiCompletion != false}
|
||||
<div>
|
||||
<CodeCompletionStatus />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { type Job, JobService, type Flow, type RestartedFrom, type OpenFlow } from '$lib/gen'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { Badge, Button, Popup } from './common'
|
||||
import { Badge, Button } from './common'
|
||||
import Popover from '$lib/components/meltComponents/Popover.svelte'
|
||||
import { createEventDispatcher, getContext } from 'svelte'
|
||||
import type { FlowEditorContext } from './flows/types'
|
||||
import { runFlowPreview } from './flows/utils'
|
||||
@@ -261,7 +262,7 @@
|
||||
</Badge>
|
||||
</Button>
|
||||
{:else}
|
||||
<Popup floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}>
|
||||
<Popover floatingConfig={{ strategy: 'absolute', placement: 'bottom-start' }}>
|
||||
<svelte:fragment slot="button">
|
||||
<Button
|
||||
title={`Re-start this flow from step ${selectedJobStep} (included).`}
|
||||
@@ -283,49 +284,51 @@
|
||||
</Badge>
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<label class="block text-primary">
|
||||
<div class="pb-1 text-sm text-secondary"
|
||||
>{selectedJobStepType == 'forloop' ? 'From iteration #:' : 'From branch:'}</div
|
||||
>
|
||||
<div class="flex w-full">
|
||||
{#if selectedJobStepType === 'forloop'}
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
bind:value={branchOrIterationN}
|
||||
class="!w-32 grow"
|
||||
on:click|stopPropagation={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<select
|
||||
bind:value={branchOrIterationN}
|
||||
class="!w-32 grow"
|
||||
on:click|stopPropagation={() => {}}
|
||||
>
|
||||
{#each restartBranchNames as [branchIdx, branchName]}
|
||||
<option value={branchIdx}>{branchName}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
<Button
|
||||
size="xs"
|
||||
color="blue"
|
||||
buttonType="button"
|
||||
btnClasses="!p-1 !w-[34px] !ml-1"
|
||||
aria-label="Restart flow"
|
||||
on:click|once={() => {
|
||||
runPreview($previewArgs, {
|
||||
flow_job_id: jobId,
|
||||
step_id: selectedJobStep,
|
||||
branch_or_iteration_n: branchOrIterationN
|
||||
})
|
||||
}}
|
||||
<svelte:fragment slot="content">
|
||||
<label class="block text-primary p-4">
|
||||
<div class="pb-1 text-sm text-secondary"
|
||||
>{selectedJobStepType == 'forloop' ? 'From iteration #:' : 'From branch:'}</div
|
||||
>
|
||||
<ArrowRight size={18} />
|
||||
</Button>
|
||||
</div>
|
||||
</label>
|
||||
</Popup>
|
||||
<div class="flex w-full">
|
||||
{#if selectedJobStepType === 'forloop'}
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
bind:value={branchOrIterationN}
|
||||
class="!w-32 grow"
|
||||
on:click|stopPropagation={() => {}}
|
||||
/>
|
||||
{:else}
|
||||
<select
|
||||
bind:value={branchOrIterationN}
|
||||
class="!w-32 grow"
|
||||
on:click|stopPropagation={() => {}}
|
||||
>
|
||||
{#each restartBranchNames as [branchIdx, branchName]}
|
||||
<option value={branchIdx}>{branchName}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
<Button
|
||||
size="xs"
|
||||
color="blue"
|
||||
buttonType="button"
|
||||
btnClasses="!p-1 !w-[34px] !ml-1"
|
||||
aria-label="Restart flow"
|
||||
on:click|once={() => {
|
||||
runPreview($previewArgs, {
|
||||
flow_job_id: jobId,
|
||||
step_id: selectedJobStep,
|
||||
branch_or_iteration_n: branchOrIterationN
|
||||
})
|
||||
}}
|
||||
>
|
||||
<ArrowRight size={18} />
|
||||
</Button>
|
||||
</div>
|
||||
</label>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
{/if}
|
||||
{/if}
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import AddUser from '$lib/components/AddUser.svelte'
|
||||
import { Badge, Button, Popup, Skeleton } from '$lib/components/common'
|
||||
import { Badge, Button, Skeleton } from '$lib/components/common'
|
||||
import Popover from '$lib/components/meltComponents/Popover.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import WorkspaceOperatorSettings from '$lib/components/settings/WorkspaceOperatorSettings.svelte'
|
||||
@@ -153,11 +154,11 @@
|
||||
<input placeholder="Filter members" bind:value={userFilter} class="input !pl-8" />
|
||||
<Search class="absolute left-2" size={14} />
|
||||
|
||||
<Popup
|
||||
<Popover
|
||||
floatingConfig={{ strategy: 'absolute', placement: 'bottom-end' }}
|
||||
containerClasses="border rounded-lg shadow-lg p-4 bg-surface"
|
||||
usePointerDownOutside
|
||||
>
|
||||
<svelte:fragment slot="button">
|
||||
<svelte:fragment slot="trigger">
|
||||
<Button
|
||||
color={auto_invite_domain != undefined ? 'green' : 'red'}
|
||||
variant="border"
|
||||
@@ -169,113 +170,115 @@
|
||||
: 'OFF'}
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="text-sm leading-6 font-semibold">
|
||||
{isCloudHosted()
|
||||
? `Auto-add anyone from ${
|
||||
auto_invite_domain != undefined ? auto_invite_domain : domain
|
||||
}`
|
||||
: `Auto-add anyone joining the instance`}
|
||||
</span>
|
||||
|
||||
{#if showInvites}
|
||||
<span class="text-xs mb-1 leading-6 pt-2"
|
||||
>Mode <Tooltip>Whether to invite or add users directly to the workspace.</Tooltip>
|
||||
<svelte:fragment slot="content">
|
||||
<div class="flex flex-col items-start p-4">
|
||||
<span class="text-sm leading-6 font-semibold">
|
||||
{isCloudHosted()
|
||||
? `Auto-add anyone from ${
|
||||
auto_invite_domain != undefined ? auto_invite_domain : domain
|
||||
}`
|
||||
: `Auto-add anyone joining the instance`}
|
||||
</span>
|
||||
|
||||
{#if showInvites}
|
||||
<span class="text-xs mb-1 leading-6 pt-2"
|
||||
>Mode <Tooltip>Whether to invite or add users directly to the workspace.</Tooltip>
|
||||
</span>
|
||||
<ToggleButtonGroup
|
||||
selected={autoAdd ? 'add' : 'invite'}
|
||||
on:selected={async (e) => {
|
||||
if (auto_invite_domain != undefined) {
|
||||
await removeAllInvitesFromDomain()
|
||||
await WorkspaceService.editAutoInvite({
|
||||
workspace: $workspaceStore ?? '',
|
||||
requestBody: {
|
||||
operator: operatorOnly ?? false,
|
||||
invite_all: !isCloudHosted(),
|
||||
auto_add: e.detail === 'add'
|
||||
}
|
||||
})
|
||||
loadSettings()
|
||||
listInvites()
|
||||
listUsers()
|
||||
} else {
|
||||
autoAdd = e.detail === 'add'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton value="invite" size="xs" label="Auto-invite" />
|
||||
<ToggleButton value="add" size="xs" label="Auto-add" />
|
||||
</ToggleButtonGroup>
|
||||
{/if}
|
||||
|
||||
<span class="text-xs mb-1 leading-6 pt-2"
|
||||
>Role <Tooltip>Role of the auto-added users</Tooltip></span
|
||||
>
|
||||
<ToggleButtonGroup
|
||||
selected={autoAdd ? 'add' : 'invite'}
|
||||
selected={operatorOnly ? 'operator' : 'developer'}
|
||||
on:selected={async (e) => {
|
||||
if (auto_invite_domain != undefined) {
|
||||
await removeAllInvitesFromDomain()
|
||||
await WorkspaceService.editAutoInvite({
|
||||
workspace: $workspaceStore ?? '',
|
||||
requestBody: {
|
||||
operator: operatorOnly ?? false,
|
||||
operator: e.detail === 'operator',
|
||||
invite_all: !isCloudHosted(),
|
||||
auto_add: e.detail === 'add'
|
||||
auto_add: showInvites ? autoAdd ?? false : true
|
||||
}
|
||||
})
|
||||
loadSettings()
|
||||
listInvites()
|
||||
listUsers()
|
||||
} else {
|
||||
autoAdd = e.detail === 'add'
|
||||
operatorOnly = e.detail === 'operator'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton value="invite" size="xs" label="Auto-invite" />
|
||||
<ToggleButton value="add" size="xs" label="Auto-add" />
|
||||
<ToggleButton
|
||||
value="operator"
|
||||
size="xs"
|
||||
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
|
||||
value="developer"
|
||||
size="xs"
|
||||
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)."
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
{/if}
|
||||
|
||||
<span class="text-xs mb-1 leading-6 pt-2"
|
||||
>Role <Tooltip>Role of the auto-added users</Tooltip></span
|
||||
>
|
||||
<ToggleButtonGroup
|
||||
selected={operatorOnly ? 'operator' : 'developer'}
|
||||
on:selected={async (e) => {
|
||||
if (auto_invite_domain != undefined) {
|
||||
await removeAllInvitesFromDomain()
|
||||
await WorkspaceService.editAutoInvite({
|
||||
workspace: $workspaceStore ?? '',
|
||||
requestBody: {
|
||||
operator: e.detail === 'operator',
|
||||
invite_all: !isCloudHosted(),
|
||||
auto_add: showInvites ? autoAdd ?? false : true
|
||||
}
|
||||
})
|
||||
loadSettings()
|
||||
listInvites()
|
||||
listUsers()
|
||||
} else {
|
||||
operatorOnly = e.detail === 'operator'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ToggleButton
|
||||
value="operator"
|
||||
size="xs"
|
||||
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
|
||||
value="developer"
|
||||
size="xs"
|
||||
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)."
|
||||
/>
|
||||
</ToggleButtonGroup>
|
||||
<div class="pt-2">
|
||||
<Toggle
|
||||
size="xs"
|
||||
checked={auto_invite_domain != undefined}
|
||||
on:change={async (e) => {
|
||||
await removeAllInvitesFromDomain()
|
||||
await WorkspaceService.editAutoInvite({
|
||||
workspace: $workspaceStore ?? '',
|
||||
requestBody: e.detail
|
||||
? {
|
||||
operator: operatorOnly ?? false,
|
||||
invite_all: !isCloudHosted(),
|
||||
auto_add: showInvites ? autoAdd ?? false : true
|
||||
}
|
||||
: { operator: undefined, auto_add: undefined }
|
||||
})
|
||||
loadSettings()
|
||||
listInvites()
|
||||
listUsers()
|
||||
}}
|
||||
disabled={isCloudHosted() && !allowedAutoDomain}
|
||||
options={{
|
||||
right: 'Enabled'
|
||||
}}
|
||||
/>
|
||||
<div class="pt-2">
|
||||
<Toggle
|
||||
size="xs"
|
||||
checked={auto_invite_domain != undefined}
|
||||
on:change={async (e) => {
|
||||
await removeAllInvitesFromDomain()
|
||||
await WorkspaceService.editAutoInvite({
|
||||
workspace: $workspaceStore ?? '',
|
||||
requestBody: e.detail
|
||||
? {
|
||||
operator: operatorOnly ?? false,
|
||||
invite_all: !isCloudHosted(),
|
||||
auto_add: showInvites ? autoAdd ?? false : true
|
||||
}
|
||||
: { operator: undefined, auto_add: undefined }
|
||||
})
|
||||
loadSettings()
|
||||
listInvites()
|
||||
listUsers()
|
||||
}}
|
||||
disabled={isCloudHosted() && !allowedAutoDomain}
|
||||
options={{
|
||||
right: 'Enabled'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{#if isCloudHosted() && !allowedAutoDomain}
|
||||
<div class="text-red-400 text-xs">{domain} domain not allowed for auto-add</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if isCloudHosted() && !allowedAutoDomain}
|
||||
<div class="text-red-400 text-xs">{domain} domain not allowed for auto-add</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Popup>
|
||||
</svelte:fragment>
|
||||
</Popover>
|
||||
<AddUser
|
||||
on:new={() => {
|
||||
listUsers()
|
||||
|
||||
Reference in New Issue
Block a user