Files
windmill/frontend/src/lib/components/sidebar/MenuButton.svelte
T
centdix d24825c3ea feat: add navigator mode to AIChat and unify UI (#5859)
* feat: ai flow chat

* youpi

* feat: preprocessor and error handler support

* fix: reactivity

* Add GlobalChat component with drawer functionality

- Create GlobalChat.svelte with placeholder chat functionality
- Create GlobalChatDrawer.svelte as drawer wrapper
- Add global chat button to sidebar menu (both mobile and desktop)
- Integrate global chat state management in main layout
- Include message history, loading states, and error handling
- Implement responsive design and proper drawer behavior

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>

* draft

* use triggerable by ai compoennt

* make drawer triggerable

* implement logic

* add inkeep tool

* cleaner code

* make more things available

* more integrations + better system prompt

* fix docs fetching

* small fix

* cleaning

* add ask in search bar + right top icon on homepage + suggestions

* fix button

* disable chat if no ai providers

* add inkeep endpoint

* draft working stuff

* cleaner code

* better chat

* fix

* send license and uid

* better anim

* move logic

* parse links in chat

* add missing integration

* add reset button

* fix

* rm file

* integrate navigator mode

* integrate all changes

* add hide button

* adjust drawer size

* add script ai chat integration

* fix drawer

* small fixes

* small fixes

* draft

* merge script ai chat with global one

* cleaning

* fixes

* working draft

* add aichat service

* cleaning more

* remove left over from store

* more descriptive states

* better icon

* fix

* use pending prompt

* cleaning

* cleaning

* small fix

* add inkeep file

* clean

* add route

* Update backend/windmill-api/src/lib.rs

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* cleaning

* fix drawer

* save open state in local storage

* small fix

* fixes

* small fixes

* move chat request to manager

* renaming

* move flow effects in manager

* move chat effects in manager

* remove log

* Update frontend/src/lib/components/copilot/CronGen.svelte

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Update frontend/src/lib/components/copilot/chat/flow/core.ts

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* change askaibutton folder

* define button

* ifelse

* no any + no default size

* use tailwind

* use splitpanes

* move effects

* remove deprecated file

* wording

* add back disable ai

* add error message

* modify system prompt

* handle confirmation modal

* fix

* fix

* close script settings

* fix icon color

* fix

* fix history manager

* fix test panel

* save size

* remove floating button

* fix delete chat

* fix

* better fix

---------

Co-authored-by: HugoCasa <hugo@casademont.ch>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: rubenfiszel <rubenfiszel@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2025-06-04 19:17:25 +02:00

123 lines
3.5 KiB
Svelte

<script lang="ts">
import { twMerge } from 'tailwind-merge'
import Popover from '../Popover.svelte'
import { createEventDispatcher } from 'svelte'
import SideBarNotification from './SideBarNotification.svelte'
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
export let stopPropagationOnClick: boolean = false
export let shortcut: string = ''
export let notificationsCount: number = 0
export let color: string | null = null
export let trigger: MenubarMenuElements['trigger'] | undefined = undefined
export let href: string | undefined = undefined
let buttonRef: HTMLButtonElement | undefined = undefined
let dispatch = createEventDispatcher()
</script>
{#if !disabled}
<Popover
appearTimeout={0}
disappearTimeout={0}
class="w-full"
disablePopup={!isCollapsed}
placement="right"
>
<TriggerableByAI
id={aiId}
description={aiDescription}
onTrigger={() => {
if (buttonRef) {
buttonRef.click()
}
}}
>
<button
bind:this={buttonRef}
on:click={(e) => {
if (stopPropagationOnClick) e.preventDefault()
if (href) {
goto(href)
}
dispatch('click')
}}
class={twMerge(
'group flex items-center px-2 py-2 font-light rounded-md h-8 gap-3 w-full',
lightMode
? 'text-primary data-[highlighted]:bg-surface-hover hover:bg-surface-hover'
: 'data-[highlighted]:bg-[#2A3648] hover:bg-[#2A3648] text-primary-inverse dark:text-primary',
color ? 'border-4' : '',
'transition-all relative',
$$props.class
)}
style={color ? `border-color: ${color}; padding: 0 calc(0.5rem - 4px);` : ''}
use:conditionalMelt={trigger}
title={isCollapsed ? undefined : label}
{...$trigger}
>
{#if icon}
<svelte:component
this={icon}
size={16}
class={twMerge(
'flex-shrink-0',
lightMode
? 'text-primary group-hover:text-secondary'
: 'text-primary-inverse group-hover:text-secondary-inverse dark:group-hover:text-secondary dark:text-primary',
'transition-all',
iconClasses
)}
/>
{/if}
{#if !isCollapsed && label}
<span
class={twMerge(
'whitespace-pre truncate',
lightMode ? 'text-primary' : 'text-primary-inverse dark:text-primary',
'transition-all',
$$props.class
)}
>
{label}
<span
class="pl-2 text-xs dark:text-secondary light:text-secondary-inverse font-semibold"
>
{shortcut}
</span>
</span>
{/if}
{#if isCollapsed && notificationsCount > 0}
<div class="absolute translate-x-1/2 translate-y-1/2 -top-2 right-1 flex h-fit w-fit">
<SideBarNotification notificationCount={notificationsCount} small={true} />
</div>
{:else if notificationsCount > 0}
<div class="ml-auto">
<SideBarNotification notificationCount={notificationsCount} small={false} />
</div>
{/if}
</button>
</TriggerableByAI>
<svelte:fragment slot="text">
{#if label}
{label}
{/if}
</svelte:fragment>
</Popover>
{/if}