Layout and design issues (#5870)

This commit is contained in:
centdix
2025-06-05 09:52:02 +02:00
committed by GitHub
parent 6d3a2d279a
commit 39b250d62c
13 changed files with 124 additions and 82 deletions
+1 -1
View File
@@ -1 +1 @@
41ada2b5729da20e7c0c90ceb06324d804136c6f
d2cf3a77ec5914339756d06a117f47db8d09b797
+32 -37
View File
@@ -81,43 +81,38 @@
<ResolveOpen {open} on:open on:close />
<TriggerableByAI id={aiId} description={aiDescription} onTrigger={() => buttonEl?.click()}>
<button
bind:this={buttonEl}
class={twMerge(
'w-full flex items-center justify-end h-full',
fixedHeight && 'h-8',
$$props.class
)}
use:melt={$trigger}
{disabled}
on:click={(e) => e.stopPropagation()}
use:pointerDownOutside={{
capture: true,
stopPropagation: false,
exclude: getMenuElements,
customEventName: 'pointerdown_menu'
}}
on:pointerdown_outside={() => {
if (usePointerDownOutside) {
close()
}
}}
data-menu
>
{#if $$slots.buttonReplacement}
<slot name="buttonReplacement" />
{:else}
<Button
nonCaptureEvent
size="xs"
color="light"
startIcon={{ icon: MoreVertical }}
btnClasses="bg-transparent"
/>
{/if}
</button>
</TriggerableByAI>
<TriggerableByAI id={aiId} description={aiDescription} onTrigger={() => buttonEl?.click()} />
<button
bind:this={buttonEl}
class={twMerge('w-full flex items-center justify-end', fixedHeight && 'h-8', $$props.class)}
use:melt={$trigger}
{disabled}
on:click={(e) => e.stopPropagation()}
use:pointerDownOutside={{
capture: true,
stopPropagation: false,
exclude: getMenuElements,
customEventName: 'pointerdown_menu'
}}
on:pointerdown_outside={() => {
if (usePointerDownOutside) {
close()
}
}}
data-menu
>
{#if $$slots.buttonReplacement}
<slot name="buttonReplacement" />
{:else}
<Button
nonCaptureEvent
size="xs"
color="light"
startIcon={{ icon: MoreVertical }}
btnClasses="bg-transparent"
/>
{/if}
</button>
{#if open && !hidePopup}
<div use:melt={$menu} data-menu class="z-[6000] transition-all duration-100">
@@ -473,7 +473,9 @@
size="md"
panelName="Test"
shortcut="U"
customHiddenIcon={PlayIcon}
customHiddenIcon={{
icon: PlayIcon
}}
on:click={() => {
toggleTestPanel()
}}
@@ -490,7 +492,9 @@
shortcut="L"
size="md"
usePopoverOverride={!$copilotInfo.enabled}
customHiddenIcon={WandSparkles}
customHiddenIcon={{
icon: WandSparkles
}}
btnClasses="!text-violet-800 dark:!text-violet-400 border border-gray-200 dark:border-gray-600 bg-surface"
on:click={() => {
aiChatManager.toggleOpen()
@@ -4,7 +4,6 @@
import Button from '$lib/components/common/button/Button.svelte'
import { getModifierKey } from '$lib/utils'
import {
type Icon,
PanelBottomClose,
PanelBottomOpen,
PanelLeftClose,
@@ -12,7 +11,6 @@
PanelRightClose,
PanelRightOpen
} from 'lucide-svelte'
import type { ComponentType } from 'svelte'
import { twMerge } from 'tailwind-merge'
export let btnClasses: string | undefined = undefined
@@ -24,7 +22,7 @@
export let hidden: boolean = false
export let shortcut: string | undefined = undefined
export let panelName: string | undefined = undefined
export let customHiddenIcon: ComponentType<Icon> | undefined = undefined
export let customHiddenIcon: ButtonType.Icon | undefined = undefined
export let usePopoverOverride: boolean = false
const OpenIconMap = {
@@ -62,9 +60,13 @@
</svelte:fragment>
<Button
iconOnly
startIcon={{
icon: hidden ? customHiddenIcon ?? OpenIconMap[direction] : CloseIconMap[direction]
}}
startIcon={hidden
? (customHiddenIcon ?? {
icon: OpenIconMap[direction]
})
: {
icon: CloseIconMap[direction]
}}
{size}
btnClasses={twMerge(
'p-1 text-gray-300 hover:!text-gray-600 dark:text-gray-500 dark:hover:!text-gray-200 bg-transparent',
@@ -296,7 +296,7 @@
aiId={aiId ? `${aiId}-dropdown` : undefined}
aiDescription={aiDescription ? `${aiDescription} dropdown` : undefined}
items={computeDropdowns(dropdownItems)}
class="h-full w-fit"
class="h-auto w-fit"
hidePopup={hideDropdown}
usePointerDownOutside
on:open={() => dispatch('dropdownOpen', true)}
@@ -81,7 +81,7 @@
class:open
class:close={!open && timeout}
class:global-chat-open={aiChatManager.open}
style={`${style}; --zIndex: ${zIndex}; --adjusted-offset: ${aiChatManager.open && placement === 'right' ? aiChatManager.size : 0}%`}
style={`${style}; --zIndex: ${zIndex}; --adjusted-offset: calc(${aiChatManager.open && placement === 'right' ? aiChatManager.size : 0}% + 4px)`}
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
@@ -1,6 +1,6 @@
<script lang="ts">
import AIChatDisplay from './AIChatDisplay.svelte'
import { onDestroy, untrack, type Snippet } from 'svelte'
import { onDestroy, untrack } from 'svelte'
import { type ScriptLang } from '$lib/gen'
import {
copilotInfo,
@@ -11,13 +11,7 @@
} from '$lib/stores'
import { aiChatManager } from './AIChatManager.svelte'
import { base } from '$lib/base'
interface Props {
headerLeft?: Snippet
headerRight?: Snippet
}
let { headerLeft, headerRight }: Props = $props()
import HideButton from '$lib/components/apps/editor/settingsPanel/HideButton.svelte'
const isAdmin = $derived($userStore?.is_admin || $userStore?.is_super_admin)
const hasCopilot = $derived($copilotInfo.enabled)
@@ -97,10 +91,22 @@
if ((e.ctrlKey || e.metaKey) && e.key === 'l') {
e.preventDefault()
aiChatManager.toggleOpen()
aiChatDisplay?.focusInput()
}
}}
/>
{#snippet headerLeft()}
<HideButton
hidden={false}
direction="right"
panelName="AI"
shortcut="L"
size="md"
on:click={() => aiChatManager.toggleOpen()}
/>
{/snippet}
<AIChatDisplay
bind:this={aiChatDisplay}
allowedModes={aiChatManager.allowedModes}
@@ -134,7 +140,6 @@
{cancel}
askAi={aiChatManager.askAi}
{headerLeft}
{headerRight}
hasDiff={aiChatManager.scriptEditorOptions &&
!!aiChatManager.scriptEditorOptions.lastDeployedCode &&
aiChatManager.scriptEditorOptions.lastDeployedCode !== aiChatManager.scriptEditorOptions.code}
@@ -60,9 +60,14 @@
} = $props()
let contextTextareaComponent: ContextTextarea | undefined = $state()
let instructionsTextarea: HTMLTextAreaElement | undefined = $state()
export function focusInput() {
contextTextareaComponent?.focus()
if (aiChatManager.mode === 'script') {
contextTextareaComponent?.focus()
} else {
instructionsTextarea?.focus()
}
}
let scrollEl: HTMLDivElement | undefined = $state()
@@ -300,6 +305,7 @@
{:else}
<div class="relative w-full px-2 scroll-pb-2 pt-2">
<textarea
bind:this={instructionsTextarea}
bind:value={aiChatManager.instructions}
use:autosize
onkeydown={(e) => {
@@ -3,9 +3,10 @@
import { copilotInfo } from '$lib/stores'
import Popover from '$lib/components/meltComponents/Popover.svelte'
import DarkPopover from '$lib/components/Popover.svelte'
import { ExternalLink, WandSparkles } from 'lucide-svelte'
import { ExternalLink } from 'lucide-svelte'
import { Button } from '$lib/components/common'
import { getModifierKey } from '$lib/utils'
import { WandSparkles } from 'lucide-svelte'
let { openPanel }: { openPanel: () => void } = $props()
</script>
@@ -1,20 +0,0 @@
<script lang="ts">
import { aiChatManager } from '../AIChatManager.svelte'
import AiChat from '../AIChat.svelte'
import HideButton from '../../../apps/editor/settingsPanel/HideButton.svelte'
</script>
<div class="relative flex flex-col h-full bg-surface z-20">
<AiChat headerLeft={aiChatHeaderLeft} />
</div>
{#snippet aiChatHeaderLeft()}
<HideButton
hidden={false}
direction="right"
panelName="AI"
shortcut="L"
size="md"
on:click={() => aiChatManager.toggleOpen()}
/>
{/snippet}
@@ -0,0 +1,38 @@
<script>
import DarkModeObserver from '../DarkModeObserver.svelte'
let { size = 24, forceDarkMode = false, className } = $props()
let darkMode = $state(false)
</script>
<DarkModeObserver bind:darkMode />
<svg
width={size}
height={size}
viewBox="0 0 65 65"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class={className}
>
<g transform="translate(0, 4.5)">
<path
d="M40.625 14L56.875 14L65 28L48.75 28L56.875 42L48.75 56L40.625 42L32.5 56L16.25 56L24.375 42L8.12502 41.9999L0 28L16.25 28L8.12499 14L16.25 1.54244e-05L24.375 14L32.5 7.2001e-05L48.75 0L40.625 14Z"
fill={darkMode || forceDarkMode ? '#8556D0' : '#E2DBFF'}
/>
<path
d="M28.6964 33.2749C28.5536 32.7039 28.265 32.1828 27.8606 31.7658C27.4563 31.3488 26.951 31.0512 26.3973 30.9039L16.5815 28.2936C16.4141 28.2446 16.2667 28.1406 16.1617 27.9974C16.0568 27.8541 16 27.6795 16 27.5C16 27.3205 16.0568 27.1459 16.1617 27.0026C16.2667 26.8594 16.4141 26.7554 16.5815 26.7064L26.3973 24.0945C26.9508 23.9473 27.456 23.6499 27.8603 23.2333C28.2646 22.8166 28.5533 22.2958 28.6964 21.7251L31.2276 11.6026C31.2746 11.4293 31.3754 11.2765 31.5145 11.1677C31.6536 11.0589 31.8234 11 31.9979 11C32.1725 11 32.3423 11.0589 32.4814 11.1677C32.6205 11.2765 32.7213 11.4293 32.7683 11.6026L35.2979 21.7251C35.4407 22.2961 35.7293 22.8172 36.1336 23.2342C36.538 23.6512 37.0433 23.9488 37.597 24.0961L47.4127 26.7047C47.5815 26.7527 47.7304 26.8565 47.8365 27.0002C47.9426 27.1438 48 27.3194 48 27.5C48 27.6806 47.9426 27.8562 47.8365 27.9998C47.7304 28.1435 47.5815 28.2473 47.4127 28.2953L37.597 30.9039C37.0433 31.0512 36.538 31.3488 36.1336 31.7658C35.7293 32.1828 35.4407 32.7039 35.2979 33.2749L32.7667 43.3974C32.7197 43.5707 32.6189 43.7235 32.4798 43.8323C32.3407 43.9411 32.1709 44 31.9963 44C31.8218 44 31.652 43.9411 31.5129 43.8323C31.3738 43.7235 31.273 43.5707 31.226 43.3974L28.6964 33.2749Z"
fill="white"
stroke={darkMode || forceDarkMode ? '#E2DBFF' : '#A76FFF'}
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M19.9676 42.75C19.923 42.5769 19.8328 42.419 19.7064 42.2927C19.5801 42.1663 19.4222 42.0761 19.2492 42.0315L16.1817 41.2405C16.1294 41.2256 16.0833 41.1941 16.0505 41.1507C16.0177 41.1073 16 41.0544 16 41C16 40.9456 16.0177 40.8927 16.0505 40.8493C16.0833 40.8059 16.1294 40.7744 16.1817 40.7595L19.2492 39.968C19.4221 39.9234 19.58 39.8333 19.7063 39.7071C19.8327 39.5808 19.9229 39.423 19.9676 39.25L20.7586 36.1826C20.7733 36.1301 20.8048 36.0838 20.8483 36.0508C20.8917 36.0178 20.9448 36 20.9994 36C21.0539 36 21.107 36.0178 21.1504 36.0508C21.1939 36.0838 21.2254 36.1301 21.2401 36.1826L22.0306 39.25C22.0752 39.4231 22.1654 39.581 22.2918 39.7073C22.4181 39.8337 22.576 39.9239 22.7491 39.9685L25.8165 40.759C25.8692 40.7736 25.9157 40.805 25.9489 40.8485C25.982 40.8921 26 40.9453 26 41C26 41.0547 25.982 41.1079 25.9489 41.1515C25.9157 41.195 25.8692 41.2264 25.8165 41.241L22.7491 42.0315C22.576 42.0761 22.4181 42.1663 22.2918 42.2927C22.1654 42.419 22.0752 42.5769 22.0306 42.75L21.2396 45.8174C21.2249 45.8699 21.1934 45.9162 21.1499 45.9492C21.1065 45.9822 21.0534 46 20.9989 46C20.9443 46 20.8912 45.9822 20.8478 45.9492C20.8043 45.9162 20.7728 45.8699 20.7581 45.8174L19.9676 42.75Z"
fill="white"
stroke={darkMode || forceDarkMode ? '#E2DBFF' : '#A76FFF'}
stroke-linecap="round"
stroke-linejoin="round"
/>
</g>
</svg>
@@ -13,6 +13,7 @@
export let label: string | undefined = undefined
export let icon: any | undefined = undefined
export let iconClasses: string | null = null
export let iconProps: any | null = null
export let isCollapsed: boolean
export let disabled: boolean = false
export let lightMode: boolean = false
@@ -80,6 +81,7 @@
'transition-all',
iconClasses
)}
{...iconProps}
/>
{/if}
@@ -53,9 +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'
import AiChat from '$lib/components/copilot/chat/AIChat.svelte'
OpenAPI.WITH_CREDENTIALS = true
let menuOpen = false
let globalSearchModal: GlobalSearchModal | undefined = undefined
@@ -456,6 +456,9 @@
on:click={() => aiChatManager.toggleOpen()}
isCollapsed={false}
icon={WandSparkles}
iconProps={{
forceDarkMode: true
}}
label="Ask AI"
class="!text-xs"
iconClasses="!text-violet-400 dark:!text-violet-400"
@@ -524,6 +527,9 @@
on:click={() => aiChatManager.toggleOpen()}
{isCollapsed}
icon={WandSparkles}
iconProps={{
forceDarkMode: true
}}
label="Ask AI"
class="!text-xs"
iconClasses="!text-violet-400 dark:!text-violet-400"
@@ -632,6 +638,9 @@
on:click={() => aiChatManager.toggleOpen()}
{isCollapsed}
icon={WandSparkles}
iconProps={{
forceDarkMode: true
}}
label="Ask AI"
class="!text-xs"
iconClasses="!text-violet-400 dark:!text-violet-400"
@@ -650,7 +659,7 @@
</div>
{/if}
<Splitpanes horizontal={false} class="flex-1 min-h-0">
<Pane size={100 - aiChatManager.size} minSize={50} class="flex flex-col min-h-0">
<Pane size={99.8 - aiChatManager.size} minSize={50} class="flex flex-col min-h-0">
<div
id="content"
class={classNames(
@@ -700,7 +709,7 @@
</div>
</Pane>
<Pane bind:size={aiChatManager.size} minSize={15} class="flex flex-col min-h-0">
<GlobalChat />
<AiChat />
</Pane>
</Splitpanes>
</div>