diff --git a/backend/windmill-api/src/inkeep_oss.rs b/backend/windmill-api/src/inkeep_oss.rs new file mode 100644 index 0000000000..ca1ffebd21 --- /dev/null +++ b/backend/windmill-api/src/inkeep_oss.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "private")] +#[allow(unused)] +pub use crate::inkeep_ee::*; + +#[cfg(not(feature = "private"))] +use axum::Router; + +#[cfg(not(feature = "private"))] +pub fn global_service() -> Router { + Router::new() +} diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index 366f4f8700..19b17e4d9d 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -93,6 +93,9 @@ pub mod http_triggers; #[cfg(feature = "private")] pub mod indexer_ee; mod indexer_oss; +#[cfg(feature = "private")] +mod inkeep_ee; +mod inkeep_oss; mod inputs; mod integration; #[cfg(feature = "postgres_trigger")] @@ -619,6 +622,7 @@ pub async fn run_server( .nest("/schedules", schedule::global_service()) .nest("/embeddings", embeddings::global_service()) .nest("/ai", ai::global_service()) + .nest("/inkeep", inkeep_oss::global_service()) .route_layer(from_extractor::()) .route_layer(from_extractor::()) .nest("/jobs", jobs::global_root_service()) diff --git a/frontend/src/lib/components/AppConnectInner.svelte b/frontend/src/lib/components/AppConnectInner.svelte index 6f73fff916..217d5981f3 100644 --- a/frontend/src/lib/components/AppConnectInner.svelte +++ b/frontend/src/lib/components/AppConnectInner.svelte @@ -63,7 +63,7 @@ (x) => passwords.includes(x) || ['token', 'secret', 'key', 'pass', 'private'].some((y) => x.toLowerCase().includes(y)) - ) + ) } let linkedSecret: string | undefined = undefined @@ -487,6 +487,8 @@ {#if !nativeLanguagesCategory.includes(key)} + buttonEl?.click()}> + + {#if open && !hidePopup}
@@ -116,7 +128,7 @@ class="bg-surface border w-56 origin-top-right rounded-md shadow-md focus:outline-none overflow-y-auto py-1 max-h-[50vh]" style={customWidth ? `width: ${customWidth}px` : ''} > - +
{/if} diff --git a/frontend/src/lib/components/DropdownV2Inner.svelte b/frontend/src/lib/components/DropdownV2Inner.svelte index 3c657d7678..9ca0be7234 100644 --- a/frontend/src/lib/components/DropdownV2Inner.svelte +++ b/frontend/src/lib/components/DropdownV2Inner.svelte @@ -4,13 +4,16 @@ import { twMerge } from 'tailwind-merge' import type { MenubarMenuElements } from '@melt-ui/svelte' import type { Item } from '$lib/utils' + import TriggerableByAI from './TriggerableByAI.svelte' + import { goto } from '$app/navigation' interface Props { + aiId?: string items?: Item[] | (() => Item[]) | (() => Promise) meltItem: MenubarMenuElements['item'] } - let { items = [], meltItem }: Props = $props() + let { aiId, items = [], meltItem }: Props = $props() let computedItems: Item[] | undefined = $state(undefined) async function computeItems() { @@ -27,29 +30,42 @@ {#if computedItems}
{#each computedItems ?? [] as item} - item?.action?.(e)} - href={item?.href} - disabled={item?.disabled} - class={twMerge( - 'px-4 py-2 text-primary font-semibold hover:bg-surface-hover cursor-pointer text-xs transition-all', - 'data-[highlighted]:bg-surface-hover', - '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 data-[highlighted]:text-red-500 data-[highlighted]:bg-red-100' - )} - item={meltItem} + { + if (item.action) { + item.action({} as MouseEvent) + } + if (item.href) { + goto(item.href) + } + }} > - {#if item.icon} - - {/if} -

- {item.displayName} -

- {@render item.extra?.()} -
+ item?.action?.(e)} + href={item?.href} + disabled={item?.disabled} + class={twMerge( + 'px-4 py-2 text-primary font-semibold hover:bg-surface-hover cursor-pointer text-xs transition-all w-full', + 'data-[highlighted]:bg-surface-hover', + '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 data-[highlighted]:text-red-500 data-[highlighted]:bg-red-100' + )} + item={meltItem} + > + {#if item.icon} + + {/if} +

+ {item.displayName} +

+ {@render item.extra?.()} +
+ {/each}
{:else} diff --git a/frontend/src/lib/components/EditorBar.svelte b/frontend/src/lib/components/EditorBar.svelte index 14fe08e45e..c2ae98599c 100644 --- a/frontend/src/lib/components/EditorBar.svelte +++ b/frontend/src/lib/components/EditorBar.svelte @@ -594,6 +594,8 @@ JsonNode ${windmillPathToCamelCaseName(path)} = JsonNode.Parse(await client.GetS
{#if showContextVarPicker && customUi?.contextVar != false} {/if} - {#if !disableAi && customUi?.topBar?.aiBuilder != false && flowEditor?.getIsAiPanelClosed()} - flowEditor?.toggleAiPanel()} /> + {#if !disableAi && customUi?.topBar?.aiBuilder != false && !aiChatManager.open} + aiChatManager.openChat()} /> {/if} { diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 5f1da5267c..c1065d356f 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -7,7 +7,8 @@ type Script, type TriggersCount, PostgresTriggerService, - CaptureService + CaptureService, + type ScriptLang } from '$lib/gen' import { inferArgs } from '$lib/infer' import { initialCode } from '$lib/script_helpers' @@ -869,6 +870,47 @@ newSavedDraftTrigers.length > 0 ? newSavedDraftTrigers : undefined } } + + function onScriptLanguageTrigger(lang: 'docker' | 'bunnative' | ScriptLang) { + if (lang == 'docker') { + if (isCloudHosted()) { + sendUserToast( + 'You cannot use Docker scripts on the multi-tenant platform. Use a dedicated instance or self-host windmill instead.', + true, + [ + { + label: 'Learn more', + callback: () => { + window.open('https://www.windmill.dev/docs/advanced/docker', '_blank') + } + } + ] + ) + return + } + template = 'docker' + } else if (lang == 'bunnative') { + template = 'bunnative' + } else { + template = 'script' + } + let language = langToLanguage(lang) + // + initContent(language, script.kind, template) + script.language = language + } + + function onSummaryChange(value: string) { + if (initialPath == '' && value?.length > 0 && !dirtyPath) { + path?.setName( + value + .toLowerCase() + .replace(/[^a-z0-9_]/g, '_') + .replace(/-+/g, '_') + .replace(/^-|-$/g, '') + ) + } + } @@ -898,18 +940,28 @@ bind:open={metadataOpen} size={selectedTab === 'ui' || selectedTab === 'triggers' ? '1200px' : '800px'} > - (metadataOpen = false)}> + (metadataOpen = false)} + aiId="script-builder-settings" + aiDescription="Script builder settings" + >
{#if customUi?.settingsPanel?.disableMetadata !== true} - Metadata + + Metadata + {/if} {#if customUi?.settingsPanel?.disableRuntime !== true} - Runtime + + Runtime + {/if} {#if customUi?.settingsPanel?.disableGeneratedUi !== true} - + Generated UI {/if} {#if customUi?.settingsPanel?.disableTriggers !== true} - + Triggers Configure how this script will be triggered. @@ -948,23 +1000,15 @@
+ {#if dropdownItems && dropdownItems.length > 0} + dispatch('dropdownOpen', true)} + on:close={() => dispatch('dropdownOpen', false)} + > + +
+ +
+
+
+ {/if} +
+ diff --git a/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte b/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte index 971cd6735d..7fa5565f57 100644 --- a/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte +++ b/frontend/src/lib/components/common/confirmationModal/UnsavedConfirmationModal.svelte @@ -12,6 +12,7 @@ } from '$lib/utils' import { page } from '$app/stores' import type { GetInitialAndModifiedValues } from './unsavedTypes' + import TriggerableByAI from '$lib/components/TriggerableByAI.svelte' export let getInitialAndModifiedValues: GetInitialAndModifiedValues = undefined export let diffDrawer: DiffDrawer | undefined = undefined @@ -67,6 +68,13 @@ }) +{#if open} + +{/if} +
diff --git a/frontend/src/lib/components/settings/TokensTable.svelte b/frontend/src/lib/components/settings/TokensTable.svelte index 9cc4f30ecb..3d4371c625 100644 --- a/frontend/src/lib/components/settings/TokensTable.svelte +++ b/frontend/src/lib/components/settings/TokensTable.svelte @@ -13,6 +13,7 @@ import ClipboardPanel from '../details/ClipboardPanel.svelte' import { sendUserToast } from '$lib/toast' import MultiSelectWrapper from '../multiselect/MultiSelectWrapper.svelte' + import TriggerableByAI from '../TriggerableByAI.svelte' // --- Props --- interface Props { @@ -101,7 +102,7 @@ label: newTokenLabel, expiration: date?.toISOString(), scopes: tokenScopes, - workspace_id: mcpMode ? (newTokenWorkspace || $workspaceStore) : newTokenWorkspace + workspace_id: mcpMode ? newTokenWorkspace || $workspaceStore : newTokenWorkspace } as NewToken }) @@ -187,6 +188,8 @@

Tokens

{/if} diff --git a/frontend/src/lib/components/sidebar/MenuButton.svelte b/frontend/src/lib/components/sidebar/MenuButton.svelte index 456416aa49..e8d350b0ae 100644 --- a/frontend/src/lib/components/sidebar/MenuButton.svelte +++ b/frontend/src/lib/components/sidebar/MenuButton.svelte @@ -6,9 +6,13 @@ import { goto } from '$app/navigation' import { conditionalMelt } from '$lib/utils' import type { MenubarMenuElements } from '@melt-ui/svelte' + import TriggerableByAI from '$lib/components/TriggerableByAI.svelte' + export let aiId: string | undefined = undefined + export let aiDescription: string | undefined = undefined export let label: string | undefined = undefined export let icon: any | undefined = undefined + export let iconClasses: string | null = null export let isCollapsed: boolean export let disabled: boolean = false export let lightMode: boolean = false @@ -19,6 +23,8 @@ export let trigger: MenubarMenuElements['trigger'] | undefined = undefined export let href: string | undefined = undefined + let buttonRef: HTMLButtonElement | undefined = undefined + let dispatch = createEventDispatcher() @@ -30,68 +36,83 @@ disablePopup={!isCollapsed} placement="right" > - + - {#if isCollapsed && notificationsCount > 0} -
- -
- {:else if notificationsCount > 0} -
- -
- {/if} - {#if label} {label} diff --git a/frontend/src/lib/components/sidebar/MenuLink.svelte b/frontend/src/lib/components/sidebar/MenuLink.svelte index 23cbe38093..88c8bb3070 100644 --- a/frontend/src/lib/components/sidebar/MenuLink.svelte +++ b/frontend/src/lib/components/sidebar/MenuLink.svelte @@ -4,7 +4,11 @@ import { navigating, page } from '$app/stores' import Popover from '../Popover.svelte' import { base } from '$app/paths' + import TriggerableByAI from '$lib/components/TriggerableByAI.svelte' + import { goto } from '$app/navigation' + export let aiId: string | undefined = undefined + export let aiDescription: string | undefined = undefined export let label: string export let href: string export let icon: any | undefined = undefined @@ -25,65 +29,73 @@ {#if !disabled} - - { + goto(href) + }} + > + + - {#if icon} - - {/if} + 'hover:transition-all', + $$props.class + )} + target={href.includes('http') ? '_blank' : null} + title={isCollapsed ? undefined : label} + use:conditionalMelt={item} + {...$item} + > + {#if icon} + + {/if} - {#if !isCollapsed} - - {label} - - {/if} - - - {label} - - + {#if !isCollapsed} + + {label} + + {/if} + + + {label} + + + {/if} diff --git a/frontend/src/lib/components/sidebar/SidebarContent.svelte b/frontend/src/lib/components/sidebar/SidebarContent.svelte index 2c4d32139e..db93b0c836 100644 --- a/frontend/src/lib/components/sidebar/SidebarContent.svelte +++ b/frontend/src/lib/components/sidebar/SidebarContent.svelte @@ -65,15 +65,37 @@ export let numUnacknowledgedCriticalAlerts = 0 $: mainMenuLinks = [ - { label: 'Home', href: `${base}/`, icon: Home }, - { label: 'Runs', href: `${base}/runs`, icon: Play }, + { + label: 'Home', + href: `${base}/`, + icon: Home, + aiId: 'sidebar-menu-link-home', + aiDescription: + "Button to navigate to home which contains all the user's scripts, flows and apps" + }, + { + label: 'Runs', + href: `${base}/runs`, + icon: Play, + aiId: 'sidebar-menu-link-runs', + aiDescription: 'Button to navigate to runs' + }, { label: 'Variables', href: `${base}/variables`, icon: DollarSign, - disabled: $userStore?.operator + disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-variables', + aiDescription: 'Button to navigate to variables' }, - { label: 'Resources', href: `${base}/resources`, icon: Boxes, disabled: $userStore?.operator } + { + label: 'Resources', + href: `${base}/resources`, + icon: Boxes, + disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-resources', + aiDescription: 'Button to navigate to resources' + } ] $: triggerMenuLinks = [ @@ -81,7 +103,9 @@ label: 'Schedules', href: `${base}/schedules`, icon: Calendar, - disabled: !SIDEBAR_SHOW_SCHEDULES || $userStore?.operator + disabled: !SIDEBAR_SHOW_SCHEDULES || $userStore?.operator, + aiId: 'sidebar-menu-link-schedules', + aiDescription: 'Button to navigate to schedules' }, ...defaultExtraTriggerLinks.filter( (link) => $usedTriggerKinds.includes(link.kind) || $page.url.pathname.includes(link.href) @@ -100,56 +124,72 @@ href: '/routes', icon: Route, disabled: $userStore?.operator, - kind: 'http' + kind: 'http', + aiId: 'sidebar-menu-link-http', + aiDescription: 'Button to navigate to HTTP routes' }, { label: 'WebSockets', href: '/websocket_triggers', icon: Unplug, disabled: $userStore?.operator, - kind: 'ws' + kind: 'ws', + aiId: 'sidebar-menu-link-ws', + aiDescription: 'Button to navigate to websocket triggers' }, { label: 'Postgres', href: '/postgres_triggers', icon: Database, disabled: $userStore?.operator, - kind: 'postgres' + kind: 'postgres', + aiId: 'sidebar-menu-link-postgres', + aiDescription: 'Button to navigate to Postgres triggers' }, { label: 'Kafka' + ($enterpriseLicense ? '' : ' (EE)'), href: '/kafka_triggers', icon: KafkaIcon, disabled: $userStore?.operator || !$enterpriseLicense, - kind: 'kafka' + kind: 'kafka', + aiId: 'sidebar-menu-link-kafka', + aiDescription: 'Button to navigate to Kafka triggers' }, { label: 'NATS' + ($enterpriseLicense ? '' : ' (EE)'), href: '/nats_triggers', icon: NatsIcon, disabled: $userStore?.operator || !$enterpriseLicense, - kind: 'nats' + kind: 'nats', + aiId: 'sidebar-menu-link-nats', + aiDescription: 'Button to navigate to NATS triggers' }, { label: 'SQS' + ($enterpriseLicense ? '' : ' (EE)'), href: '/sqs_triggers', icon: AwsIcon, disabled: $userStore?.operator || !$enterpriseLicense, - kind: 'sqs' + kind: 'sqs', + aiId: 'sidebar-menu-link-sqs', + aiDescription: 'Button to navigate to SQS triggers' }, { label: 'GCP Pub/Sub' + ($enterpriseLicense ? '' : ' (EE)'), href: '/gcp_triggers', icon: GoogleCloudIcon, disabled: $userStore?.operator || !$enterpriseLicense, - kind: 'gcp' + kind: 'gcp', + aiId: 'sidebar-menu-link-gcp', + aiDescription: 'Button to navigate to GCP Pub/Sub triggers' }, { label: 'MQTT', href: '/mqtt_triggers', icon: MqttIcon, disabled: $userStore?.operator, - kind: 'mqtt' + kind: 'mqtt', + aiId: 'sidebar-menu-link-mqtt', + aiDescription: 'Button to navigate to MQTT triggers' } ] @@ -166,11 +206,16 @@ { label: 'Settings', icon: Settings, + aiId: 'sidebar-menu-link-settings', + aiDescription: + 'Button to navigate to settings, including account, workspace, and instance settings', subItems: [ { label: 'Account', href: '#user-settings', icon: UserCog, + aiId: 'sidebar-menu-link-account', + aiDescription: 'Button to navigate to account settings', faIcon: undefined }, ...($userStore?.is_admin || $superadmin @@ -179,6 +224,8 @@ label: 'Workspace', href: `${base}/workspace_settings`, icon: FolderCog, + aiId: 'sidebar-menu-link-workspace', + aiDescription: 'Button to navigate to workspace settings', faIcon: undefined } ] @@ -189,6 +236,8 @@ label: 'Instance', href: '#superadmin-settings', icon: ServerCog, + aiId: 'sidebar-menu-link-instance', + aiDescription: 'Button to navigate to instance settings', faIcon: undefined } ] @@ -209,16 +258,27 @@ ], disabled: $userStore?.operator }, - { label: 'Workers', href: `${base}/workers`, icon: Bot, disabled: $userStore?.operator }, + { + label: 'Workers', + href: `${base}/workers`, + icon: Bot, + disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-workers', + aiDescription: 'Button to navigate to workers' + }, { label: 'Folders & Groups', icon: FolderOpen, + aiId: 'sidebar-menu-link-folders-groups', + aiDescription: 'Button to navigate to folders and groups', subItems: [ { label: 'Folders', href: `${base}/folders`, icon: FolderOpen, disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-folders', + aiDescription: 'Button to navigate to folders', faIcon: undefined }, { @@ -226,6 +286,8 @@ href: `${base}/groups`, icon: UserCog, disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-groups', + aiDescription: 'Button to navigate to groups', faIcon: undefined } ], @@ -235,18 +297,24 @@ ? { label: 'Logs', icon: Logs, + aiId: 'sidebar-menu-link-logs', + aiDescription: 'Button to navigate to logs', subItems: [ { label: 'Audit logs', href: `${base}/audit_logs`, - icon: Eye + icon: Eye, + aiId: 'sidebar-menu-link-audit-logs', + aiDescription: 'Button to navigate to audit logs' }, ...($devopsRole ? [ { label: 'Service logs', href: `${base}/service_logs`, - icon: Logs + icon: Logs, + aiId: 'sidebar-menu-link-service-logs', + aiDescription: 'Button to navigate to service logs' } ] : []), @@ -258,7 +326,9 @@ isCriticalAlertsUIOpen.set(true) }, icon: AlertCircle, - notificationCount: numUnacknowledgedCriticalAlerts + notificationCount: numUnacknowledgedCriticalAlerts, + aiId: 'sidebar-menu-link-critical-alerts', + aiDescription: 'Button to navigate to critical alerts' } ] : []) @@ -268,7 +338,9 @@ label: 'Audit logs', href: `${base}/audit_logs`, icon: Eye, - disabled: $userStore?.operator + disabled: $userStore?.operator, + aiId: 'sidebar-menu-link-audit-logs', + aiDescription: 'Button to navigate to audit logs' } ] @@ -298,21 +370,33 @@ label: 'Help', icon: HelpCircle, subItems: [ - { label: 'Docs', href: 'https://www.windmill.dev/docs/intro/', icon: BookOpen }, + { + label: 'Docs', + href: 'https://www.windmill.dev/docs/intro/', + icon: BookOpen, + aiId: 'sidebar-menu-link-docs', + aiDescription: 'Button to navigate to docs' + }, { label: 'Feedbacks', href: 'https://discord.gg/V7PM2YHsPB', - icon: DiscordIcon + icon: DiscordIcon, + aiId: 'sidebar-menu-link-feedbacks', + aiDescription: 'Button to navigate to feedbacks' }, { label: 'Issues', href: 'https://github.com/windmill-labs/windmill/issues/new', - icon: Github + icon: Github, + aiId: 'sidebar-menu-link-issues', + aiDescription: 'Button to navigate to issues' }, { label: 'Changelog', href: 'https://www.windmill.dev/changelog/', - icon: Newspaper + icon: Newspaper, + aiId: 'sidebar-menu-link-changelog', + aiDescription: 'Button to navigate to changelog' } ] } @@ -370,6 +454,8 @@ {#each extraTriggerLinks as subItem (subItem.href ?? subItem.label)} { subItem?.['action']?.() }} + aiId={subItem.aiId} + aiDescription={subItem.aiDescription} >
{#if subItem.icon} diff --git a/frontend/src/lib/components/triggers/TriggersTable.svelte b/frontend/src/lib/components/triggers/TriggersTable.svelte index 2d225a09ac..4309e5f105 100644 --- a/frontend/src/lib/components/triggers/TriggersTable.svelte +++ b/frontend/src/lib/components/triggers/TriggersTable.svelte @@ -7,6 +7,7 @@ import AddTriggersButton from './AddTriggersButton.svelte' import TriggerLabel from './TriggerLabel.svelte' import DeleteTriggerButton from './DeleteTriggerButton.svelte' + import TriggerableByAI from '../TriggerableByAI.svelte' interface Props { // Props @@ -41,6 +42,8 @@
- +
+ + {/each} diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts index 3eddc0876d..f6d2e42685 100644 --- a/frontend/src/lib/stores.ts +++ b/frontend/src/lib/stores.ts @@ -105,7 +105,6 @@ export const copilotInfo = writable<{ defaultModel: undefined, aiModels: [] }) -export const chatMode = writable<'script' | 'flow'>('script') export function setCopilotInfo(aiConfig: AIConfig) { if (Object.keys(aiConfig.providers ?? {}).length > 0) { diff --git a/frontend/src/routes/(root)/(logged)/+layout.svelte b/frontend/src/routes/(root)/(logged)/+layout.svelte index dc3876ffc5..09598a52e0 100644 --- a/frontend/src/routes/(root)/(logged)/+layout.svelte +++ b/frontend/src/routes/(root)/(logged)/+layout.svelte @@ -43,7 +43,7 @@ import { SUPERADMIN_SETTINGS_HASH, USER_SETTINGS_HASH } from '$lib/components/sidebar/settings' import { isCloudHosted } from '$lib/cloud' import { syncTutorialsTodos } from '$lib/tutorialUtils' - import { ArrowLeft, Search } from 'lucide-svelte' + import { ArrowLeft, Search, WandSparkles } from 'lucide-svelte' import { getUserExt } from '$lib/user' import { workspaceAIClients } from '$lib/components/copilot/lib' import { twMerge } from 'tailwind-merge' @@ -53,7 +53,9 @@ import { setContext } from 'svelte' import { base } from '$app/paths' import { Menubar } from '$lib/components/meltComponents' - + import GlobalChat from '$lib/components/copilot/chat/navigator/GlobalChat.svelte' + import { aiChatManager } from '$lib/components/copilot/chat/AIChatManager.svelte' + import { Pane, Splitpanes } from 'svelte-splitpanes' OpenAPI.WITH_CREDENTIALS = true let menuOpen = false let globalSearchModal: GlobalSearchModal | undefined = undefined @@ -367,7 +369,7 @@ {#if mountModal} {/if} -
+
{#if !menuHidden} {#if !$userStore?.operator} {#if innerWidth < 768} @@ -449,6 +451,15 @@ class="!text-xs" shortcut={`${getModifierKey()}k`} /> + aiChatManager.toggleOpen()} + isCollapsed={false} + icon={WandSparkles} + label="Ask AI" + class="!text-xs" + iconClasses="!text-violet-400 dark:!text-violet-400" + />
+ aiChatManager.toggleOpen()} + {isCollapsed} + icon={WandSparkles} + label="Ask AI" + class="!text-xs" + iconClasses="!text-violet-400 dark:!text-violet-400" + />
@@ -607,6 +627,15 @@ class="!text-xs" shortcut={`${getModifierKey()}k`} /> + aiChatManager.toggleOpen()} + {isCollapsed} + icon={WandSparkles} + label="Ask AI" + class="!text-xs" + iconClasses="!text-violet-400 dark:!text-violet-400" + />
{/if} -
-
-
-
- -
- + +
+
+ +
+
+ - - + + + + + {:else} diff --git a/frontend/src/routes/(root)/(logged)/+page.svelte b/frontend/src/routes/(root)/(logged)/+page.svelte index 784716770d..bfba2b4744 100644 --- a/frontend/src/routes/(root)/(logged)/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/+page.svelte @@ -214,7 +214,7 @@
-
+
{#if $workspaceStore == 'admins'}
@@ -227,7 +227,7 @@
{#if !$userStore?.operator} Create a - + {#if HOME_SHOW_CREATE_FLOW}{/if} {#if HOME_SHOW_CREATE_APP}{/if} {/if} diff --git a/frontend/src/routes/(root)/(logged)/resources/+page.svelte b/frontend/src/routes/(root)/(logged)/resources/+page.svelte index 5816ba85f9..05fa69eba7 100644 --- a/frontend/src/routes/(root)/(logged)/resources/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/resources/+page.svelte @@ -616,10 +616,23 @@ documentationLink="https://www.windmill.dev/docs/core_concepts/resources_and_types" >
- -
diff --git a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte index ec1feb8aff..4b59add981 100644 --- a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte @@ -256,8 +256,14 @@ tooltip="Trigger Scripts and Flows according to a cron schedule" documentationLink="https://www.windmill.dev/docs/core_concepts/scheduling" > -
diff --git a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte index 77593756cc..539018a5ab 100644 --- a/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/workspace_settings/+page.svelte @@ -644,46 +644,106 @@ goto(`?${$page.url.searchParams.toString()}`) }} > - +
Users
- +
Git Sync
- +
Deployment UI
{#if WORKSPACE_SHOW_SLACK_CMD} - +
Slack / Teams
{/if} {#if isCloudHosted()} - +
Premium Plans
{/if} {#if WORKSPACE_SHOW_WEBHOOK_CLI_SYNC} - +
Webhook
{/if} - +
Error Handler
- +
Windmill AI
- +
Object Storage (S3)
- +
Default App
- +
Encryption
- +
General