Files
windmill/frontend/src/lib/components/workspaceSettings/InstanceFallbackSettings.svelte
T
GuilhemandClaude Opus 5 705c90debd feat(frontend): add missing resource type icons and show them in the resource picker (#10407)
* feat(frontend): add missing resource type icons and show them in the picker

Anthropic, DeepSeek, OpenRouter, Google AI (Gemini) and Ultravox resource
types rendered as a blank grey circle. Add their marks and wire up two icons
that already existed in the repo but were never imported.

Unmapped resource types now fall back to the generic resource glyph instead
of the grey circle, and the resource picker shows the icon before the path —
both in the dropdown rows and inside the input — omitting it entirely, with
no reserved padding, when the type has no icon.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(frontend): correct gemini gradient units and reuse the icon resolver

The Gemini gradient omitted gradientUnits, so its 0..24 coordinates were read
as objectBoundingBox fractions and the whole mark collapsed onto a 4% slice of
the ramp — a flat purple. Pin it to userSpaceOnUse like every other gradient
icon in the directory.

Index the resource list by path once instead of scanning it per dropdown row,
fold the two remaining inline copies of the icon lookup into appIconComponent,
and drop the sendflake key — no resource type by that name exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style(frontend): shrink the resource picker icon to 14px

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style(frontend): drop the redundant frame around the ai providers list

SettingCard already supplies p-4, rounded-md and bg-surface-tertiary, so the
wrapper repeated all three and added a border, nesting a card inside a card.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(frontend): keep the unregistered snowflake mark, extend the card fix

SendflakeIcon is the Snowflake logo under a misleading filename, not a
different product; SnowflakeIcon is the same logo with a baked-in ® that
shrinks and off-centres the flake and turns to a smudge at 14-24px. Leave the
mapping where it was.

Apply the card-in-card removal to the two InstanceFallbackSettings cards that
stack directly above the AI providers one, so the frames stay consistent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(frontend): make the ansible mark legible on dark surfaces

Mapping `ansible` renders this icon for the first time, and its near-black disc
disappears into the dark surface, leaving only the white "A" counter floating.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 23:40:03 +02:00

106 lines
3.1 KiB
Svelte

<script lang="ts">
import { type AIProvider, type InstanceAISummary } from '$lib/gen'
import { AI_PROVIDERS } from '../copilot/lib'
import Badge from '../common/badge/Badge.svelte'
import Button from '../common/button/Button.svelte'
import SettingCard from '../instanceSettings/SettingCard.svelte'
interface Props {
instanceAiSummary?: InstanceAISummary
showWorkspaceOverrideEditor?: boolean
onToggleOverride: () => void
}
let {
instanceAiSummary = undefined,
showWorkspaceOverrideEditor = false,
onToggleOverride
}: Props = $props()
let sortedInstanceProviders = $derived(
[...(instanceAiSummary?.providers ?? [])].sort((left, right) =>
left.provider.localeCompare(right.provider)
)
)
function getProviderLabel(provider: AIProvider): string {
return AI_PROVIDERS[provider]?.label ?? provider
}
</script>
{#if instanceAiSummary}
<SettingCard label="Active instance AI">
<div class="flex flex-col gap-4">
<p class="text-xs text-secondary">
This workspace is currently using the instance AI defaults shown below.
</p>
<div class="flex flex-col gap-3">
{#each sortedInstanceProviders as providerSummary (providerSummary.provider)}
<div class="rounded-md border bg-surface p-3 flex flex-col gap-2">
<div class="flex items-center gap-2">
<span class="text-xs font-medium">
{getProviderLabel(providerSummary.provider)}
</span>
<Badge color="blue">Instance</Badge>
</div>
<div class="flex flex-wrap gap-1">
{#each providerSummary.models as model (model)}
<Badge color="gray">{model}</Badge>
{/each}
</div>
</div>
{/each}
</div>
{#if instanceAiSummary.default_model}
<div class="text-xs text-secondary">
Default chat model:
<span class="text-primary font-medium">{instanceAiSummary.default_model.model}</span>
<span class="text-tertiary">
({getProviderLabel(instanceAiSummary.default_model.provider)})
</span>
</div>
{/if}
{#if instanceAiSummary.metadata_model}
<div class="text-xs text-secondary">
Metadata generation model:
<span class="text-primary font-medium">
{instanceAiSummary.metadata_model.model}
</span>
<span class="text-tertiary">
({getProviderLabel(instanceAiSummary.metadata_model.provider)})
</span>
</div>
{/if}
{#if instanceAiSummary.code_completion_model}
<div class="text-xs text-secondary">
Code completion model:
<span class="text-primary font-medium">
{instanceAiSummary.code_completion_model.model}
</span>
<span class="text-tertiary">
({getProviderLabel(instanceAiSummary.code_completion_model.provider)})
</span>
</div>
{/if}
</div>
</SettingCard>
{/if}
<SettingCard label="Workspace override">
<div class="flex flex-col gap-3">
<p class="text-xs text-secondary">
Create workspace-specific AI settings only if this workspace needs to override the active
instance defaults.
</p>
<div>
<Button onclick={onToggleOverride} variant="default" unifiedSize="sm">
{showWorkspaceOverrideEditor ? 'Hide override form' : 'Override for this workspace'}
</Button>
</div>
</div>
</SettingCard>