Skip to content

Commit

Permalink
feat(frontend): add quick access menu in flow editor (windmill-labs#4415
Browse files Browse the repository at this point in the history
)

* (frontend) add quick access menu in flow editor

* (frontend) add quick access menu in flow editor

* improve UI

* make design prettier

* add scroll effects

* improve loading preview

* change no items found

* prevent scroll using menu

* change user folder button

* set default integration icon

* reduce column width

* ajust font

* add defaults script button

* add shadow divider

* fix scroll

* add chevron

* Change toogle bar

* Add preprocessor menu

* add handler

* simplify scroll

* fix display

* fix minor issues

* delete useless log

* revert node tree changes

* merge main

* fix z-index issues

* iterate

* fix: improve allowed domains setting for sso

* chore(main): release 1.402.3 (windmill-labs#4458)

* chore(main): release 1.402.3

* Apply automatic changes

---------

Co-authored-by: rubenfiszel <[email protected]>

* improve allowed domains change handling

* send stats when renewing key if last >24h (windmill-labs#4430)

* feat: send stats when renewing key if last >24h

* nits

* fix: sqlx

* nit

* renewal reason

* stats reason

* update ee ref

* Update ee-repo-ref.txt

---------

Co-authored-by: Ruben Fiszel <[email protected]>

* fix: skip one migration to avoid using md5 for azure support

* all

* all

* Apply automatic changes

* all

* done?

* nit

* nit

* nit

* nit

* nit noAi if prefilter is not all

* fix shadow

* fix error handler

* fix error handler

* Polishing default script settings

* all

* all

* full

* all

* add deno_core as features

* all

* remove warnings

* all

* npm check

* npm check

* new script script

* nits

* nits item 0

* nits item 0

---------

Co-authored-by: Guilhem Le Mouel <[email protected]>
Co-authored-by: Ruben Fiszel <[email protected]>
Co-authored-by: Ruben Fiszel <[email protected]>
Co-authored-by: rubenfiszel <[email protected]>
Co-authored-by: HugoCasa <[email protected]>
Co-authored-by: Guilhem <[email protected]>
  • Loading branch information
7 people authored Oct 3, 2024
1 parent 48a85e1 commit 45ccd45
Show file tree
Hide file tree
Showing 39 changed files with 1,995 additions and 341 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Add down migration script here
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- Add up migration script here
ALTER TYPE SCRIPT_KIND ADD VALUE IF NOT EXISTS 'preprocessor';
8 changes: 8 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@
"svelte": "./package/components/icons/WindmillIcon.svelte",
"default": "./package/components/icons/WindmillIcon.svelte"
},
"./components/icons/WindmillIcon2.svelte": {
"types": "./package/components/icons/WindmillIcon2.d.ts",
"svelte": "./package/components/icons/WindmillIcon2.svelte",
"default": "./package/components/icons/WindmillIcon2.svelte"
},
"./components/IconedResourceType.svelte": {
"types": "./package/components/IconedResourceType.svelte.d.ts",
"svelte": "./package/components/IconedResourceType.svelte",
Expand Down Expand Up @@ -358,6 +363,9 @@
"components/icons/WindmillIcon.svelte": [
"./package/components/icons/WindmillIcon.svelte.d.ts"
],
"components/icons/WindmillIcon2.svelte": [
"./package/components/icons/WindmillIcon2.svelte.d.ts"
],
"components/scriptEditor/LogPanel.svelte": [
"./package/components/scriptEditor/LogPanel.svelte.d.ts"
],
Expand Down
12 changes: 9 additions & 3 deletions frontend/src/lib/components/DefaultScripts.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
import DefaultScriptsInner from './DefaultScriptsInner.svelte'
let drawer: Drawer
export let placement: 'left' | 'right' = 'left'
export let size: 'xs3' | 'xs2' = 'xs2'
export let noText = false
</script>

{#if $userStore?.is_admin || $userStore?.is_super_admin}
<Drawer bind:this={drawer} placement="left">
<Drawer bind:this={drawer} {placement}>
<DrawerContent title="Edit Default Scripts" on:close={drawer.closeDrawer}>
<DefaultScriptsInner />
</DrawerContent>
Expand All @@ -19,8 +23,10 @@
on:click={drawer?.openDrawer}
startIcon={{ icon: SettingsIcon }}
color="light"
size="xs2"
{size}
btnClasses="!text-tertiary"
variant="contained">defaults</Button
variant="contained"
>
{noText ? '' : 'defaults'}
</Button>
{/if}
23 changes: 16 additions & 7 deletions frontend/src/lib/components/DefaultScriptsInner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { defaultScriptLanguages } from '$lib/scripts'
import Alert from './common/alert/Alert.svelte'
export let small = false
$: langs = computeLangs($defaultScripts)
function computeLangs(defaultScripts: WorkspaceDefaultScripts | undefined): Script['language'][] {
Expand All @@ -31,24 +32,32 @@
}
</script>

<Alert title="Global to workspace" type="info" class="mb-4">
<Alert title="Global to workspace" type="info" class="mb-4" size={small ? 'xs' : 'sm'}>
This setting is only available to admins and will affect all users in the workspace.
</Alert>
<div class="h-full w-full flex-col gap-2 flex">
<div class="h-full w-full flex-col {small ? 'gap-0' : 'gap-2'} flex">
{#each langs as lang, i (lang)}
<div
animate:flip={{ duration: 300 }}
class="w-full p-2 rounded border border-seconadry grid grid-cols-3"
><h3>{lang}</h3>
class="w-full p-2 rounded {small
? ''
: 'border border-secondary'} grid grid-cols-3 items-center"
><h3 class={small ? 'text-xs font-medium justify-center' : ''}>{lang}</h3>
<div>
{#if i > 0}
<button on:click={() => changePosition(i ?? 0, true)} class="text-lg mr-2">
<button
on:click={() => changePosition(i ?? 0, true)}
class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'}
title="Move up"
>
&uparrow;</button
>
{/if}
{#if i < langs.length - 1}
<button on:click={() => changePosition(i ?? 0, false)} class="text-lg mr-2"
>&downarrow;</button
<button
on:click={() => changePosition(i ?? 0, false)}
class={small ? 'mr-2 text-secondary text-sm' : 'text-lg mr-2'}
title="Move down">&downarrow;</button
>
{/if}</div
>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/lib/components/Dev.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@
saveDraft: () => {},
initialPath: '',
flowInputsStore: writable<FlowInput>({}),
customUi: {}
customUi: {},
insertButtonOpen: writable(false)
})
$: updateFlow($flowStore)
Expand Down
33 changes: 21 additions & 12 deletions frontend/src/lib/components/FlowBuilder.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
selectedIdStore.set(selectedId)
}
let insertButtonOpen = writable<boolean>(false)
setContext<FlowEditorContext>('FlowEditorContext', {
selectedId: selectedIdStore,
schedule: scheduleStore,
Expand All @@ -408,7 +409,8 @@
saveDraft,
initialPath,
flowInputsStore: writable<FlowInput>({}),
customUi
customUi,
insertButtonOpen
})
async function loadSchedule() {
Expand Down Expand Up @@ -461,20 +463,24 @@
}
break
case 'ArrowDown': {
let ids = generateIds()
let idx = ids.indexOf($selectedIdStore)
if (idx > -1 && idx < ids.length - 1) {
$selectedIdStore = ids[idx + 1]
event.preventDefault()
if (!$insertButtonOpen) {
let ids = generateIds()
let idx = ids.indexOf($selectedIdStore)
if (idx > -1 && idx < ids.length - 1) {
$selectedIdStore = ids[idx + 1]
event.preventDefault()
}
}
break
}
case 'ArrowUp': {
let ids = generateIds()
let idx = ids.indexOf($selectedIdStore)
if (idx > 0 && idx < ids.length) {
$selectedIdStore = ids[idx - 1]
event.preventDefault()
if (!$insertButtonOpen) {
let ids = generateIds()
let idx = ids.indexOf($selectedIdStore)
if (idx > 0 && idx < ids.length) {
$selectedIdStore = ids[idx - 1]
event.preventDefault()
}
}
break
}
Expand Down Expand Up @@ -561,6 +567,8 @@
kind: string
app: string
ask_id: number
id: number
version_id: number
}[]
} catch (err) {
if (err.name !== 'CancelError') throw err
Expand Down Expand Up @@ -890,7 +898,8 @@
const snakeKey = snakeCase(key)
if (
schemaProperty &&
(!$flowStore.schema || !(snakeKey in ($flowStore.schema.properties as any) ?? {})) // prevent overriding flow inputs
(!$flowStore.schema ||
!(snakeKey in ($flowStore?.schema?.properties ?? ({} as any)))) // prevent overriding flow inputs
) {
copilotFlowInputs[snakeKey] = schemaProperty
if (schema?.required.includes(snakeKey)) {
Expand Down
57 changes: 57 additions & 0 deletions frontend/src/lib/components/Scrollable.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte'
import { twMerge } from 'tailwind-merge'
let isAtBottom: boolean = false
let isScrollable = false
export let scrollableClass: string = ''
export let shiftedShadow: boolean = false
let mutationObserver: MutationObserver
let el: HTMLDivElement
function handleScroll(event) {
const scrollableElement = event.target
isAtBottom =
scrollableElement.scrollTop + scrollableElement.offsetHeight >=
scrollableElement.scrollHeight - 2
}
function checkIfScrollable(el) {
return el.scrollHeight > el.clientHeight
}
function observeScrollability(el) {
isScrollable = checkIfScrollable(el)
mutationObserver = new MutationObserver(() => {
isScrollable = checkIfScrollable(el)
})
mutationObserver?.observe(el, { childList: true, subtree: true, characterData: true })
}
export function scrollIntoView(top: number) {
el.scrollTo({ top, behavior: 'smooth' })
}
onMount(() => {
observeScrollability(el)
})
onDestroy(() => {
mutationObserver?.disconnect()
})
</script>

<div class={twMerge('relative pb-1', scrollableClass)}>
<div bind:this={el} on:scroll={handleScroll} class="w-full h-full overflow-y-auto">
<slot />
</div>
{#if !isAtBottom && isScrollable}
<div
class="pointer-events-none absolute bottom-0 {shiftedShadow
? 'left-2'
: 'right-0'} h-14 w-full bg-gradient-to-t from-surface to-transparent"
/>
{/if}
</div>
15 changes: 15 additions & 0 deletions frontend/src/lib/components/ToggleHubWorkspaceQuick.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { WindmillIcon2 } from './icons'
import ToggleButtonGroup from './common/toggleButton-v2/ToggleButtonGroup.svelte'
import ToggleButton from './common/toggleButton-v2/ToggleButton.svelte'
import { Building } from 'lucide-svelte'
export let selected: 'all' | 'hub' | 'workspace' = 'all'
</script>

<div class="max-w-min">
<ToggleButtonGroup bind:selected>
<ToggleButton value="all" label="All" light small />
<ToggleButton value="hub" icon={WindmillIcon2} label="Hub" light small />
<ToggleButton value="workspace" icon={Building} label="Workspace" light small />
</ToggleButtonGroup>
</div>
3 changes: 2 additions & 1 deletion frontend/src/lib/components/common/menu/Menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
'bottom-start': 'origin-top-left left-0',
'bottom-end': 'origin-top-right right-0',
'top-start': 'origin-bottom-left left-0 bottom-0',
'top-end': 'origin-bottom-right right-0 bottom-0'
'top-end': 'origin-bottom-right right-0 bottom-0',
'top-center': 'origin-top-left -top-full left-1/2 transform -translate-x-1/2 -translate-y-full'
}
const dispatch = createEventDispatcher()
</script>
Expand Down
35 changes: 22 additions & 13 deletions frontend/src/lib/components/common/popup/Popup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
}
export let containerClasses: string = 'rounded-lg shadow-md border p-4 bg-surface'
export let floatingClasses: string = ''
const [floatingRef, floatingContent] = createFloatingActions(floatingConfig)
export let blockOpen = false
export let shouldUsePortal: boolean = true
export let target: string | HTMLElement | undefined = undefined
export let noTransition = false
</script>

<Popover on:close class="leading-none">
Expand All @@ -24,22 +25,30 @@
</div>
</PopoverButton>
<ConditionalPortal condition={shouldUsePortal} {target}>
<div use:floatingContent class="z5000">
<Transition
show={blockOpen || undefined}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<PopoverPanel let:close static={blockOpen}>
<div use:floatingContent class={`z5000 ${floatingClasses}`}>
{#if !noTransition}
<Transition
show={blockOpen || undefined}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<PopoverPanel let:close static={blockOpen}>
<div class={containerClasses}>
<slot {close} />
</div>
</PopoverPanel>
</Transition>
{:else}
<PopoverPanel focus={false} let:close static={blockOpen}>
<div class={containerClasses}>
<slot {close} />
</div>
</PopoverPanel>
</Transition>
{/if}
</div>
</ConditionalPortal>
</Popover>
63 changes: 63 additions & 0 deletions frontend/src/lib/components/common/popup/PopupV2.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script lang="ts">
import Portal from '$lib/components/Portal.svelte'
import { clickOutside } from '$lib/utils'
import { createFloatingActions, type ComputeConfig } from 'svelte-floating-ui'
export let floatingConfig: ComputeConfig = {
strategy: 'absolute',
//@ts-ignore
placement: 'bottom-center'
}
export let open = false
export let target: string | undefined = undefined
// export let containerClasses: string = 'rounded-lg shadow-md border p-4 bg-surface'
// export let floatingClasses: string = ''
const [floatingRef, floatingContent] = createFloatingActions(floatingConfig)
function close(div: Element | null) {
open = false
}
let acceptClickoutside = false
function pointerup() {
setTimeout(() => {
acceptClickoutside = true
}, 100)
}
function pointerdown() {
if (acceptClickoutside && open) {
open = false
} else {
acceptClickoutside = false
open = true
}
}
</script>

<div use:floatingRef>
<slot {pointerup} {pointerdown} name="button" />
</div>

<Portal {target}>
{#if open}
<div
class="border rounded-lg shadow-lg bg-surface z5000"
style="position:absolute"
use:floatingContent
>
<div
use:clickOutside
on:click_outside={() => {
if (acceptClickoutside) {
acceptClickoutside = false
open = false
}
}}
>
<slot {close} />
</div>
</div>
{/if}
</Portal>
Loading

0 comments on commit 45ccd45

Please sign in to comment.