Files
windmill/frontend/src/lib/components/WorkspaceDraftsBanner.svelte
T
GuilhemandClaude Fable 5 ad0fef4a2e feat(ai-chat): recall queued/last message into the composer (#10191)
* feat(ai-chat): recall queued/last message into input via ArrowUp or chip click

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ai-chat): cycle chat mode with Shift+Tab, keep full message in chip tooltip

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ai-chat): only cycle mode on Shift+Tab when the textarea is focused

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* revert(ai-chat): drop Shift+Tab mode cycling, it conflicts with browser shortcuts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ai-chat): only recall on ArrowUp when the textarea is focused

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ai-chat): make ArrowUp recall image-aware, unnest the queued-chip controls

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align workspace banners with page content padding and round corners

* fix(ai): recall attachments and context chips on ArrowUp, unnest chip buttons

* fix(ai): skip synthetic auto-resume turns in ArrowUp recall boundary

* fix(ai): defer recall during in-flight sends, make synthetic flag per-send

* fix(ai): gate recall on send-in-flight, not loading

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 08:57:15 +02:00

52 lines
2.2 KiB
Svelte

<script lang="ts">
import { workspaceStore, userWorkspaces } from '$lib/stores'
import { workspaceIsFork } from '$lib/utils/workspaceHierarchy'
import { Button } from './common'
import { Pencil } from 'lucide-svelte'
import { goto } from '$app/navigation'
import { useWorkspaceDrafts } from '$lib/workspaceDrafts.svelte'
// Surfaces pending drafts (scripts/flows/apps) for the current workspace and
// links to the compare page in draft mode. Mutually exclusive with
// ForkWorkspaceBanner: that one self-gates on `isFork`, this one on `!isFork`,
// so a fork workspace never shows both. In a fork, drafts are discovered via
// the on-page "Deployed ↔ draft (N)" toggle badge instead.
let isFork = $derived(workspaceIsFork($workspaceStore, $userWorkspaces))
// Count comes from the shared Workspace Drafts resource (count ≡ the draft
// list; refreshes itself on deploy/discard). Pass undefined in a fork or with
// no workspace so it doesn't fetch and the banner stays hidden.
const drafts = useWorkspaceDrafts(() => (!isFork ? ($workspaceStore ?? undefined) : undefined))
const draftCount = $derived(drafts.count)
function openDraftCompare() {
if ($workspaceStore) {
goto('/forks/compare?workspace_id=' + encodeURIComponent($workspaceStore) + '&mode=draft', {
replaceState: true
})
}
}
</script>
{#if !isFork && draftCount > 0}
<!-- Side padding mirrors the page content container below, so the banner
stays aligned with it instead of bleeding to the viewport edges. -->
<div class="w-full text-xs max-w-7xl mx-auto px-4 sm:px-8 pt-2">
<div class="bg-blue-50 dark:bg-blue-900 rounded-md px-4 py-2">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<Pencil class="w-4 h-4 text-accent" />
<span class="text-xs font-medium text-blue-900 dark:text-blue-100">
This workspace has {draftCount} draft{draftCount !== 1 ? 's' : ''}
</span>
</div>
<!-- Same button as the sibling ForkWorkspaceBanner CTA (they sit on the
same home page), kept visually identical on purpose. -->
<Button variant="default" unifiedSize="sm" onclick={openDraftCompare}>
Review & deploy drafts
</Button>
</div>
</div>
</div>
{/if}