mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 00:01:55 +00:00
deploy ui homepage call optimization
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { MoreVertical } from 'lucide-svelte'
|
||||
import Menu from './common/menu/MenuV2.svelte'
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
import DropdownV2Inner from './DropdownV2Inner.svelte'
|
||||
|
||||
type Item = {
|
||||
displayName: string
|
||||
@@ -14,12 +14,12 @@
|
||||
hide?: boolean | undefined
|
||||
}
|
||||
|
||||
export let items: Item[] | (() => Item[]) = []
|
||||
export let items: Item[] | (() => Item[]) | (() => Promise<Item[]>) = []
|
||||
export let justifyEnd: boolean = true
|
||||
|
||||
function computeItems(): Item[] {
|
||||
async function computeItems(): Promise<Item[]> {
|
||||
if (typeof items === 'function') {
|
||||
return (items() ?? []).filter((item) => !item.hide)
|
||||
return ((await items()) ?? []).filter((item) => !item.hide)
|
||||
} else {
|
||||
return items.filter((item) => !item.hide)
|
||||
}
|
||||
@@ -38,26 +38,5 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
{#each computeItems() ?? [] as item}
|
||||
<MenuItem
|
||||
on:click={(e) => item?.action?.(e)}
|
||||
href={item?.href}
|
||||
disabled={item?.disabled}
|
||||
class={twMerge(
|
||||
'px-4 py-2 text-primary hover:bg-surface-hover hover:text-primary cursor-pointer text-xs transition-all',
|
||||
'flex flex-row gap-2 items-center',
|
||||
item?.disabled && 'text-gray-400 cursor-not-allowed',
|
||||
item?.type === 'delete' &&
|
||||
!item?.disabled &&
|
||||
'text-red-500 hover:bg-red-100 hover:text-red-500'
|
||||
)}
|
||||
>
|
||||
{#if item.icon}
|
||||
<svelte:component this={item.icon} size={14} />
|
||||
{/if}
|
||||
{item.displayName}
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</div>
|
||||
<DropdownV2Inner items={computeItems} />
|
||||
</Menu>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<script lang="ts">
|
||||
import { MenuItem } from '@rgossiaux/svelte-headlessui'
|
||||
import { Loader2 } from 'lucide-svelte'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
type Item = {
|
||||
displayName: string
|
||||
action?: (e: CustomEvent<any>) => void
|
||||
icon?: any
|
||||
href?: string
|
||||
disabled?: boolean
|
||||
type?: 'action' | 'delete'
|
||||
hide?: boolean | undefined
|
||||
}
|
||||
|
||||
export let items: Item[] | (() => Item[]) | (() => Promise<Item[]>) = []
|
||||
|
||||
let computedItems: Item[] | undefined = undefined
|
||||
async function computeItems() {
|
||||
if (typeof items === 'function') {
|
||||
computedItems = ((await items()) ?? []).filter((item) => !item.hide)
|
||||
} else {
|
||||
computedItems = items.filter((item) => !item.hide)
|
||||
}
|
||||
}
|
||||
|
||||
computeItems()
|
||||
</script>
|
||||
|
||||
{#if computedItems}
|
||||
<div class="flex flex-col">
|
||||
{#each computedItems ?? [] as item}
|
||||
<MenuItem
|
||||
on:click={(e) => item?.action?.(e)}
|
||||
href={item?.href}
|
||||
disabled={item?.disabled}
|
||||
class={twMerge(
|
||||
'px-4 py-2 text-primary hover:bg-surface-hover hover:text-primary cursor-pointer text-xs transition-all',
|
||||
'flex flex-row gap-2 items-center',
|
||||
item?.disabled && 'text-gray-400 cursor-not-allowed',
|
||||
item?.type === 'delete' &&
|
||||
!item?.disabled &&
|
||||
'text-red-500 hover:bg-red-100 hover:text-red-500'
|
||||
)}
|
||||
>
|
||||
{#if item.icon}
|
||||
<svelte:component this={item.icon} size={14} />
|
||||
{/if}
|
||||
{item.displayName}
|
||||
</MenuItem>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<Loader2 class="animate-spin mx-auto p-4" size={24} />
|
||||
{/if}
|
||||
@@ -4,12 +4,7 @@
|
||||
import type MoveDrawer from '$lib/components/MoveDrawer.svelte'
|
||||
import SharedBadge from '$lib/components/SharedBadge.svelte'
|
||||
import type ShareModal from '$lib/components/ShareModal.svelte'
|
||||
import {
|
||||
AppService,
|
||||
DraftService,
|
||||
type ListableApp,
|
||||
type WorkspaceDeployUISettings
|
||||
} from '$lib/gen'
|
||||
import { AppService, DraftService, type ListableApp } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Button from '../button/Button.svelte'
|
||||
@@ -37,6 +32,7 @@
|
||||
import AppDeploymentHistory from '$lib/components/apps/editor/AppDeploymentHistory.svelte'
|
||||
import AppJsonEditor from '$lib/components/apps/editor/AppJsonEditor.svelte'
|
||||
import { isDeployable } from '$lib/utils_deployable'
|
||||
import { getDeployUiSettings } from '$lib/components/home/deploy_ui'
|
||||
|
||||
export let app: ListableApp & { has_draft?: boolean; draft_only?: boolean; canWrite: boolean }
|
||||
export let marked: string | undefined
|
||||
@@ -47,7 +43,6 @@
|
||||
export let deleteConfirmedCallback: (() => void) | undefined
|
||||
export let depth: number = 0
|
||||
export let menuOpen: boolean = false
|
||||
export let deployUiSettings: WorkspaceDeployUISettings | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -120,7 +115,7 @@
|
||||
{/if}
|
||||
</span>
|
||||
<Dropdown
|
||||
items={() => {
|
||||
items={async () => {
|
||||
let { draft_only, canWrite, summary, execution_mode, path, has_draft } = app
|
||||
|
||||
if (draft_only) {
|
||||
@@ -170,7 +165,7 @@
|
||||
disabled: !canWrite,
|
||||
hide: $userStore?.operator
|
||||
},
|
||||
...(isDeployable('app', path, deployUiSettings)
|
||||
...(isDeployable('app', path, await getDeployUiSettings())
|
||||
? [
|
||||
{
|
||||
displayName: 'Deploy to staging/prod',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import ScheduleEditor from '$lib/components/ScheduleEditor.svelte'
|
||||
import SharedBadge from '$lib/components/SharedBadge.svelte'
|
||||
import type ShareModal from '$lib/components/ShareModal.svelte'
|
||||
import { FlowService, type Flow, DraftService, type WorkspaceDeployUISettings } from '$lib/gen'
|
||||
import { FlowService, type Flow, DraftService } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Badge from '../badge/Badge.svelte'
|
||||
@@ -33,6 +33,7 @@
|
||||
HistoryIcon
|
||||
} from 'lucide-svelte'
|
||||
import FlowHistory from '$lib/components/flows/FlowHistory.svelte'
|
||||
import { getDeployUiSettings } from '$lib/components/home/deploy_ui'
|
||||
|
||||
export let flow: Flow & { has_draft?: boolean; draft_only?: boolean; canWrite: boolean }
|
||||
export let marked: string | undefined
|
||||
@@ -44,7 +45,6 @@
|
||||
export let errorHandlerMuted: boolean
|
||||
export let depth: number = 0
|
||||
export let menuOpen: boolean = false
|
||||
export let deployUiSettings: WorkspaceDeployUISettings | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
</span>
|
||||
|
||||
<Dropdown
|
||||
items={() => {
|
||||
items={async () => {
|
||||
let { draft_only, path, archived, has_draft } = flow
|
||||
let owner = isOwner(path, $userStore, $workspaceStore)
|
||||
if (draft_only) {
|
||||
@@ -193,7 +193,7 @@
|
||||
copyToClipboard(path)
|
||||
}
|
||||
},
|
||||
...(isDeployable('flow', path, deployUiSettings)
|
||||
...(isDeployable('flow', path, await getDeployUiSettings())
|
||||
? [
|
||||
{
|
||||
displayName: 'Deploy to staging/prod',
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type MoveDrawer from '$lib/components/MoveDrawer.svelte'
|
||||
import SharedBadge from '$lib/components/SharedBadge.svelte'
|
||||
import type ShareModal from '$lib/components/ShareModal.svelte'
|
||||
import { RawAppService, type ListableRawApp, type WorkspaceDeployUISettings } from '$lib/gen'
|
||||
import { RawAppService, type ListableRawApp } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Button from '../button/Button.svelte'
|
||||
@@ -16,6 +16,7 @@
|
||||
import type DeployWorkspaceDrawer from '$lib/components/DeployWorkspaceDrawer.svelte'
|
||||
import { FileUp, Globe, Pen, Share, Trash } from 'lucide-svelte'
|
||||
import { isDeployable } from '$lib/utils_deployable'
|
||||
import { getDeployUiSettings } from '$lib/components/home/deploy_ui'
|
||||
|
||||
export let app: ListableRawApp & { canWrite: boolean }
|
||||
export let marked: string | undefined
|
||||
@@ -26,7 +27,6 @@
|
||||
export let deploymentDrawer: DeployWorkspaceDrawer
|
||||
export let depth: number = 0
|
||||
export let menuOpen: boolean = false
|
||||
export let deployUiSettings: WorkspaceDeployUISettings | undefined = undefined
|
||||
|
||||
let updateAppDrawer: Drawer
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
{/if}
|
||||
</span>
|
||||
<Dropdown
|
||||
items={() => {
|
||||
items={async () => {
|
||||
let { summary, path, canWrite } = app
|
||||
|
||||
return [
|
||||
@@ -100,7 +100,7 @@
|
||||
},
|
||||
disabled: !canWrite
|
||||
},
|
||||
...(isDeployable('app', path, deployUiSettings)
|
||||
...(isDeployable('app', path, await getDeployUiSettings())
|
||||
? [
|
||||
{
|
||||
displayName: 'Deploy to prod/staging',
|
||||
|
||||
@@ -7,12 +7,7 @@
|
||||
import SharedBadge from '$lib/components/SharedBadge.svelte'
|
||||
import type ShareModal from '$lib/components/ShareModal.svelte'
|
||||
|
||||
import {
|
||||
ScriptService,
|
||||
type Script,
|
||||
DraftService,
|
||||
type WorkspaceDeployUISettings
|
||||
} from '$lib/gen'
|
||||
import { ScriptService, type Script, DraftService } from '$lib/gen'
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
@@ -44,6 +39,7 @@
|
||||
import { Drawer, DrawerContent } from '..'
|
||||
import NoMainFuncBadge from '$lib/components/NoMainFuncBadge.svelte'
|
||||
import Tooltip from '$lib/components/Tooltip.svelte'
|
||||
import { getDeployUiSettings } from '$lib/components/home/deploy_ui'
|
||||
|
||||
export let script: Script & { canWrite: boolean; use_codebase: boolean }
|
||||
export let marked: string | undefined
|
||||
@@ -56,7 +52,6 @@
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
export let depth: number = 0
|
||||
export let menuOpen: boolean = false
|
||||
export let deployUiSettings: WorkspaceDeployUISettings | undefined = undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -166,7 +161,7 @@
|
||||
{/if}
|
||||
</span>
|
||||
<Dropdown
|
||||
items={() => {
|
||||
items={async () => {
|
||||
let owner = isOwner(script.path, $userStore, $workspaceStore)
|
||||
if (script.draft_only) {
|
||||
return [
|
||||
@@ -219,7 +214,7 @@
|
||||
disabled: !owner || script.archived,
|
||||
hide: $userStore?.operator
|
||||
},
|
||||
...(isDeployable('script', script.path, deployUiSettings)
|
||||
...(isDeployable('script', script.path, await getDeployUiSettings())
|
||||
? [
|
||||
{
|
||||
displayName: 'Deploy to staging/prod',
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
import ShareModal from '../ShareModal.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { ArrowBigUp } from 'lucide-svelte'
|
||||
import { enterpriseLicense, workspaceStore } from '$lib/stores'
|
||||
import { WorkspaceService, type WorkspaceDeployUISettings } from '$lib/gen'
|
||||
import { ALL_DEPLOYABLE } from '$lib/utils_deployable'
|
||||
|
||||
export let item
|
||||
export let depth: number = 0
|
||||
@@ -26,19 +23,6 @@
|
||||
|
||||
let menuOpen: boolean = false
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
|
||||
let deployUiSettings: WorkspaceDeployUISettings | undefined = undefined
|
||||
|
||||
async function getDeployUiSettings() {
|
||||
if (!$enterpriseLicense) {
|
||||
deployUiSettings = ALL_DEPLOYABLE
|
||||
return
|
||||
}
|
||||
let settings = await WorkspaceService.getSettings({ workspace: $workspaceStore! })
|
||||
deployUiSettings = settings.deploy_ui ?? ALL_DEPLOYABLE
|
||||
}
|
||||
getDeployUiSettings()
|
||||
|
||||
</script>
|
||||
|
||||
{#if item.type == 'script'}
|
||||
@@ -58,7 +42,6 @@
|
||||
{depth}
|
||||
bind:menuOpen
|
||||
{showCode}
|
||||
{deployUiSettings}
|
||||
/>
|
||||
{:else if item.type == 'flow'}
|
||||
<FlowRow
|
||||
@@ -76,7 +59,6 @@
|
||||
{deploymentDrawer}
|
||||
{depth}
|
||||
bind:menuOpen
|
||||
{deployUiSettings}
|
||||
/>
|
||||
{:else if item.type == 'app'}
|
||||
<AppRow
|
||||
@@ -90,7 +72,6 @@
|
||||
{deploymentDrawer}
|
||||
{depth}
|
||||
bind:menuOpen
|
||||
{deployUiSettings}
|
||||
/>
|
||||
{:else if item.type == 'raw_app'}
|
||||
<RawAppRow
|
||||
@@ -104,7 +85,6 @@
|
||||
{deploymentDrawer}
|
||||
{depth}
|
||||
bind:menuOpen
|
||||
{deployUiSettings}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { enterpriseLicense, workspaceStore } from '$lib/stores'
|
||||
import { WorkspaceService, type WorkspaceDeployUISettings } from '$lib/gen'
|
||||
import { ALL_DEPLOYABLE } from '$lib/utils_deployable'
|
||||
import { get, writable } from 'svelte/store'
|
||||
|
||||
const deployUiStore = writable<Record<string, WorkspaceDeployUISettings>>({})
|
||||
export async function getDeployUiSettings(): Promise<WorkspaceDeployUISettings> {
|
||||
let deployUiSettings = get(deployUiStore)
|
||||
let workspace = get(workspaceStore)
|
||||
if (!deployUiSettings[workspace!]) {
|
||||
deployUiSettings[workspace!] = await getDeployUiSettingsInner()
|
||||
deployUiStore.set(deployUiSettings)
|
||||
}
|
||||
return deployUiSettings[workspace!]
|
||||
}
|
||||
|
||||
async function getDeployUiSettingsInner(): Promise<WorkspaceDeployUISettings> {
|
||||
if (!get(enterpriseLicense)) {
|
||||
return ALL_DEPLOYABLE
|
||||
}
|
||||
let settings = await WorkspaceService.getSettings({ workspace: get(workspaceStore)! })
|
||||
return settings.deploy_ui ?? ALL_DEPLOYABLE
|
||||
}
|
||||
Reference in New Issue
Block a user