mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-04 16:03:06 +00:00
use melt menu for FavoriteMenu and WorkspaceMenu
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
const menu = createMenu({
|
||||
positioning: {
|
||||
placement
|
||||
}
|
||||
},
|
||||
loop: true
|
||||
})
|
||||
|
||||
//Melt
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { Code2, LayoutDashboard, Star } from 'lucide-svelte'
|
||||
import BarsStaggered from '$lib/components/icons/BarsStaggered.svelte'
|
||||
|
||||
import Menu from '../common/menu/MenuV2.svelte'
|
||||
import MenuButton from './MenuButton.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { melt } from '@melt-ui/svelte'
|
||||
import Menu from '$lib/components/meltComponents/Menu.svelte'
|
||||
import MenuButtonMelt from '$lib/components/sidebar/MenuButtonMelt.svelte'
|
||||
export let lightMode: boolean = false
|
||||
|
||||
export let isCollapsed: boolean = false
|
||||
@@ -13,12 +12,20 @@
|
||||
href: string
|
||||
kind: 'script' | 'flow' | 'app' | 'raw_app'
|
||||
}[]
|
||||
export let createMenu: any
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<div slot="trigger">
|
||||
<MenuButton class="!text-xs" icon={Star} label={'Favorites'} {isCollapsed} {lightMode} />
|
||||
</div>
|
||||
<Menu {createMenu} let:item>
|
||||
<svelte:fragment slot="trigger" let:trigger>
|
||||
<MenuButtonMelt
|
||||
class="!text-xs"
|
||||
icon={Star}
|
||||
label={'Favorites'}
|
||||
{isCollapsed}
|
||||
{lightMode}
|
||||
{trigger}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="overflow-hidden" role="none">
|
||||
{#if !favoriteLinks.length}
|
||||
@@ -30,22 +37,24 @@
|
||||
{:else}
|
||||
<div class="py-1 w-full max-w-full">
|
||||
{#each favoriteLinks ?? [] as favorite (favorite.href)}
|
||||
<MenuItem href={favorite.href}>
|
||||
<span class="w-full inline-flex flex-row px-4 py-2 hover:bg-surface-hover">
|
||||
<span class="center-center">
|
||||
{#if favorite.kind == 'script'}
|
||||
<Code2 size={16} />
|
||||
{:else if favorite.kind == 'flow'}
|
||||
<BarsStaggered size={16} />
|
||||
{:else if favorite.kind == 'app' || favorite.kind == 'raw_app'}
|
||||
<LayoutDashboard size={16} />
|
||||
{/if}
|
||||
</span>
|
||||
<span class="text-primary ml-2 grow min-w-0 text-xs truncate">
|
||||
{favorite.label}
|
||||
</span>
|
||||
<a
|
||||
href={favorite.href}
|
||||
use:melt={item}
|
||||
class="w-full inline-flex flex-row px-4 py-2 hover:bg-surface-hover data-[highlighted]:bg-surface-hover"
|
||||
>
|
||||
<span class="center-center">
|
||||
{#if favorite.kind == 'script'}
|
||||
<Code2 size={16} />
|
||||
{:else if favorite.kind == 'flow'}
|
||||
<BarsStaggered size={16} />
|
||||
{:else if favorite.kind == 'app' || favorite.kind == 'raw_app'}
|
||||
<LayoutDashboard size={16} />
|
||||
{/if}
|
||||
</span>
|
||||
</MenuItem>
|
||||
<span class="text-primary ml-2 grow min-w-0 text-xs truncate">
|
||||
{favorite.label}
|
||||
</span>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -8,21 +8,21 @@
|
||||
workspaceUsageStore
|
||||
} from '$lib/stores'
|
||||
import { Building, Plus, Settings } from 'lucide-svelte'
|
||||
|
||||
import Menu from '../common/menu/MenuV2.svelte'
|
||||
import MenuButtonMelt from '$lib/components/sidebar/MenuButtonMelt.svelte'
|
||||
import Menu from '$lib/components/meltComponents/Menu.svelte'
|
||||
import { melt } from '@melt-ui/svelte'
|
||||
import { goto } from '$lib/navigation'
|
||||
import { base } from '$lib/base'
|
||||
import { page } from '$app/stores'
|
||||
import { switchWorkspace } from '$lib/storeUtils'
|
||||
import MultiplayerMenu from './MultiplayerMenu.svelte'
|
||||
import { enterpriseLicense } from '$lib/stores'
|
||||
import MenuButton from './MenuButton.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { isCloudHosted } from '$lib/cloud'
|
||||
import { initAllAiWorkspace } from '../copilot/lib'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export let isCollapsed: boolean = false
|
||||
export let createMenu: any
|
||||
|
||||
// When used outside of the side bar, where links to workspace settings and such don't make as much sense.
|
||||
export let strictWorkspaceSelect = false
|
||||
@@ -54,48 +54,50 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<Menu>
|
||||
<div slot="trigger">
|
||||
<MenuButton
|
||||
<Menu {createMenu} let:item>
|
||||
<svelte:fragment slot="trigger" let:trigger>
|
||||
<MenuButtonMelt
|
||||
class="!text-xs"
|
||||
icon={Building}
|
||||
label={$workspaceStore ?? ''}
|
||||
{isCollapsed}
|
||||
color={$userWorkspaces.find((w) => w.id === $workspaceStore)?.color}
|
||||
{trigger}
|
||||
/>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="divide-y" role="none">
|
||||
<div class="py-1">
|
||||
{#each $userWorkspaces as workspace}
|
||||
<MenuItem>
|
||||
<button
|
||||
class={twMerge(
|
||||
'text-xs min-w-0 w-full overflow-hidden flex flex-col py-1.5',
|
||||
$workspaceStore === workspace.id
|
||||
? 'cursor-default bg-surface-selected'
|
||||
: 'cursor-pointer hover:bg-surface-hover'
|
||||
)}
|
||||
on:click={async () => {
|
||||
await toggleSwitchWorkspace(workspace.id)
|
||||
}}
|
||||
>
|
||||
<div class="flex items-center justify-between min-w-0 w-full">
|
||||
<div>
|
||||
<div class="text-primary pl-4 truncate text-left text-[1.2em]">{workspace.name}</div>
|
||||
<div class="text-tertiary font-mono pl-4 text-2xs whitespace-nowrap truncate text-left">
|
||||
{workspace.id}
|
||||
</div>
|
||||
<button
|
||||
class={twMerge(
|
||||
'text-xs min-w-0 w-full overflow-hidden flex flex-col py-1.5',
|
||||
$workspaceStore === workspace.id
|
||||
? 'cursor-default bg-surface-selected'
|
||||
: 'cursor-pointer hover:bg-surface-hover data-[highlighted]:bg-surface-hover'
|
||||
)}
|
||||
on:click={async () => {
|
||||
await toggleSwitchWorkspace(workspace.id)
|
||||
}}
|
||||
use:melt={item}
|
||||
>
|
||||
<div class="flex items-center justify-between min-w-0 w-full">
|
||||
<div>
|
||||
<div class="text-primary pl-4 truncate text-left text-[1.2em]">{workspace.name}</div>
|
||||
<div
|
||||
class="text-tertiary font-mono pl-4 text-2xs whitespace-nowrap truncate text-left"
|
||||
>
|
||||
{workspace.id}
|
||||
</div>
|
||||
{#if workspace.color}
|
||||
<div
|
||||
class="w-5 h-5 mr-2 rounded border border-gray-300 dark:border-gray-600"
|
||||
style="background-color: {workspace.color}"
|
||||
></div>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
</MenuItem>
|
||||
{#if workspace.color}
|
||||
<div
|
||||
class="w-5 h-5 mr-2 rounded border border-gray-300 dark:border-gray-600"
|
||||
style="background-color: {workspace.color}"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{#if (isCloudHosted() || $superadmin) && !strictWorkspaceSelect}
|
||||
@@ -118,9 +120,13 @@
|
||||
on:click={() => {
|
||||
localStorage.removeItem('workspace')
|
||||
}}
|
||||
class="text-primary block px-4 py-2 text-xs hover:bg-surface-hover hover:text-primary"
|
||||
class={twMerge(
|
||||
'text-primary block px-4 py-2 text-xs hover:bg-surface-hover hover:text-primary',
|
||||
'data-[highlighted]:bg-surface-hover data-[highlighted]:text-primary'
|
||||
)}
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
use:melt={item}
|
||||
>
|
||||
All workspaces
|
||||
</a>
|
||||
@@ -128,17 +134,19 @@
|
||||
{/if}
|
||||
{#if ($userStore?.is_admin || $superadmin) && !strictWorkspaceSelect}
|
||||
<div class="py-1" role="none">
|
||||
<MenuItem>
|
||||
<a
|
||||
href="{base}/workspace_settings"
|
||||
class="text-secondary px-4 py-2 text-xs hover:bg-surface-hover hover:text-primary flex flex-flow gap-2"
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
>
|
||||
<Settings size={16} />
|
||||
Workspace settings
|
||||
</a>
|
||||
</MenuItem>
|
||||
<a
|
||||
href="{base}/workspace_settings"
|
||||
class={twMerge(
|
||||
'text-secondary px-4 py-2 text-xs hover:bg-surface-hover hover:text-primary flex flex-flow gap-2',
|
||||
'data-[highlighted]:bg-surface-hover data-[highlighted]:text-primary'
|
||||
)}
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
use:melt={item}
|
||||
>
|
||||
<Settings size={16} />
|
||||
Workspace settings
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -158,12 +166,16 @@
|
||||
{#if $userStore?.is_admin}
|
||||
<button
|
||||
type="button"
|
||||
class="text-secondary block font-normal w-full text-left px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900"
|
||||
class={twMerge(
|
||||
'text-secondary block font-normal w-full text-left px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900',
|
||||
'data-[highlighted]:bg-gray-100 data-[highlighted]:text-gray-900'
|
||||
)}
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
on:click={() => {
|
||||
goto('/workspace_settings?tab=premium')
|
||||
}}
|
||||
use:melt={item}
|
||||
>
|
||||
Upgrade
|
||||
</button>
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
import MenuButton from '$lib/components/sidebar/MenuButton.svelte'
|
||||
import { setContext } from 'svelte'
|
||||
import { base } from '$app/paths'
|
||||
import Menubar from '$lib/components/meltComponents/Menubar.svelte'
|
||||
|
||||
OpenAPI.WITH_CREDENTIALS = true
|
||||
let menuOpen = false
|
||||
@@ -192,11 +193,9 @@
|
||||
async function loadUsedTriggerKinds() {
|
||||
let usedKinds: string[] = []
|
||||
const { http_routes_used, websocket_used, kafka_used, postgres_used, nats_used } =
|
||||
await WorkspaceService.getUsedTriggers(
|
||||
{
|
||||
workspace: $workspaceStore ?? ''
|
||||
}
|
||||
)
|
||||
await WorkspaceService.getUsedTriggers({
|
||||
workspace: $workspaceStore ?? ''
|
||||
})
|
||||
if (http_routes_used) {
|
||||
usedKinds.push('http')
|
||||
}
|
||||
@@ -294,7 +293,13 @@
|
||||
setContext('openSearchWithPrefilledText', openSearchModal)
|
||||
|
||||
$: {
|
||||
if ($enterpriseLicense && $workspaceStore && $userStore && $devopsRole !== undefined && ($devopsRole || $userStore.is_admin)) {
|
||||
if (
|
||||
$enterpriseLicense &&
|
||||
$workspaceStore &&
|
||||
$userStore &&
|
||||
$devopsRole !== undefined &&
|
||||
($devopsRole || $userStore.is_admin)
|
||||
) {
|
||||
mountModal = true
|
||||
loadCriticalAlertsMuted()
|
||||
}
|
||||
@@ -409,8 +414,10 @@
|
||||
Windmill
|
||||
</div>
|
||||
<div class="px-2 py-4 space-y-2 border-y border-gray-500">
|
||||
<WorkspaceMenu />
|
||||
<FavoriteMenu {favoriteLinks} />
|
||||
<Menubar let:createMenu>
|
||||
<WorkspaceMenu {createMenu} />
|
||||
<FavoriteMenu {createMenu} {favoriteLinks} />
|
||||
</Menubar>
|
||||
<MenuButton
|
||||
stopPropagationOnClick={true}
|
||||
on:click={() => openSearchModal()}
|
||||
@@ -462,8 +469,10 @@
|
||||
</div>
|
||||
</button>
|
||||
<div class="px-2 py-4 space-y-2 border-y border-gray-700">
|
||||
<WorkspaceMenu {isCollapsed} />
|
||||
<FavoriteMenu {favoriteLinks} {isCollapsed} />
|
||||
<Menubar let:createMenu>
|
||||
<WorkspaceMenu {createMenu} {isCollapsed} />
|
||||
<FavoriteMenu {createMenu} {favoriteLinks} {isCollapsed} />
|
||||
</Menubar>
|
||||
<MenuButton
|
||||
stopPropagationOnClick={true}
|
||||
on:click={() => openSearchModal()}
|
||||
@@ -555,8 +564,10 @@
|
||||
</div>
|
||||
|
||||
<div class="px-2 py-4 space-y-2 border-y border-gray-500">
|
||||
<WorkspaceMenu />
|
||||
<FavoriteMenu {favoriteLinks} />
|
||||
<Menubar let:createMenu>
|
||||
<WorkspaceMenu {createMenu} />
|
||||
<FavoriteMenu {createMenu} {favoriteLinks} />
|
||||
</Menubar>
|
||||
<MenuButton
|
||||
stopPropagationOnClick={true}
|
||||
on:click={() => openSearchModal()}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { generateRandomString } from '$lib/utils'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import WorkspaceMenu from '$lib/components/sidebar/WorkspaceMenu.svelte'
|
||||
import Menubar from '$lib/components/meltComponents/Menubar.svelte'
|
||||
|
||||
let itemPath: string | undefined = undefined
|
||||
let itemKind: 'script' | 'flow' | 'app' = 'script'
|
||||
@@ -95,7 +96,9 @@
|
||||
<div class="flex flex-col items-center gap-3 w-full">
|
||||
<div class="flex flex-row items-center justify-center w-full">
|
||||
<span class="flex justify-end w-full items-right"> Selected Workspace: </span>
|
||||
<WorkspaceMenu strictWorkspaceSelect />
|
||||
<Menubar let:createMenu>
|
||||
<WorkspaceMenu strictWorkspaceSelect {createMenu} />
|
||||
</Menubar>
|
||||
</div>
|
||||
<ScriptPicker
|
||||
allowEdit={false}
|
||||
|
||||
Reference in New Issue
Block a user