refactor(ui): extract providerLogo snippet and restyle provider icons

Introduce a reusable providerLogo snippet to consolidate logo markup (normal
and large variants) and to render the instance badge for self-hosted GitLab.
Replace duplicated inline SVG spans with {@render providerLogo(...)} calls.

Also:
- update the Azure DevOps SVG path (comment notes simple-icons v11.15.0 as source)
- add providerColor cases for gitea and azure-devops and expose light-theme
  CSS vars for their colors
- overhaul provider logo CSS (sizes, brand-icon class, instance badge, borders
  and theme-aware vars) to unify appearance and spacing.
This commit is contained in:
2026-09-11 23:01:23 +02:00
parent d26d2ac982
commit 385b6304fa
@@ -23,9 +23,10 @@
const current = $derived<GitIntegrationConfig | AzureDevOpsOrganization | undefined>(selected === "azure-devops" ? selectedAzureOrganization : settings.providers[selected]);
const currentAccountId = $derived(selected === "azure-devops" ? selectedAzureOrganization?.id : undefined);
// Azure DevOps path: simple-icons/simple-icons, tag 11.15.0 (icons/azuredevops.svg).
const azureDevOpsIcon: SimpleIcon = {
title: "Azure DevOps", slug: "azuredevops", hex: "0078D4", source: "https://azure.microsoft.com/products/devops", svg: "",
path: "M0 8.877 2.247 5.91l8.405-3.416v19.127l-8.405-3.53L0 15.123V8.877Zm12.154-6.968 11.846 2.423v15.336l-11.846 2.423V1.909Z",
path: "M0 8.877L2.247 5.91l8.405-3.416V.022l7.37 5.393L2.966 8.338v8.225L0 15.707zm24-4.45v14.651l-5.753 4.9-9.303-3.057v3.056l-5.978-7.416 15.057 1.798V5.415z",
};
const providerIcons: Record<GitIntegrationProvider, SimpleIcon> = { github: siGithub, gitlab: siGitlab, "gitlab-self-hosted": siGitlab, "azure-devops": azureDevOpsIcon, gitea: siGitea };
@@ -37,6 +38,8 @@
}
function providerColor(provider: GitIntegrationProvider): string {
if (provider === "gitea") return "var(--provider-gitea-ink, #85c64a)";
if (provider === "azure-devops") return "var(--provider-azure-ink, #3da9f4)";
return provider === "github" ? "var(--color-ink)" : `#${providerIcons[provider].hex}`;
}
@@ -161,11 +164,19 @@
}
</script>
{#snippet providerLogo(provider: GitIntegrationProvider, large = false)}
<span class="provider-logo" class:provider-logo-large={large} style={`--provider-color:${providerColor(provider)}`} aria-hidden="true">
<svg class="provider-brand-icon" viewBox="0 0 24 24"><path d={providerIcons[provider].path} /></svg>
{#if provider === "gitlab-self-hosted"}<span class="provider-instance-badge"><Server size={10} strokeWidth={2}/></span>{/if}
</span>
{/snippet}
<div class="integration-layout">
<div class="integration-providers" role="tablist" aria-label={isGerman ? "Git-Anbieter" : "Git providers"}>
{#each gitIntegrationProviders as provider}
<button type="button" role="tab" aria-selected={selected === provider} class:active={selected === provider} onclick={() => selectProvider(provider)}>
<span class="provider-logo" style={`--provider-color:${providerColor(provider)}`}><svg viewBox="0 0 24 24" aria-hidden="true"><path d={providerIcons[provider].path} /></svg></span>
{@render providerLogo(provider)}
<span class="provider-copy"><strong>{providerLabel(provider)}</strong><small>{providerDescription(provider)}</small></span>
<span class="provider-state" class:configured={isConfigured(provider)} title={isConfigured(provider) ? (isGerman ? "Konfiguriert" : "Configured") : (isGerman ? "Nicht verbunden" : "Not connected")}></span>
</button>
@@ -174,7 +185,7 @@
<section class="integration-config" aria-label={`${providerLabel(selected)} ${isGerman ? "konfigurieren" : "configuration"}`}>
<header class="integration-summary">
<span class="provider-logo provider-logo-large" style={`--provider-color:${providerColor(selected)}`}><svg viewBox="0 0 24 24" aria-hidden="true"><path d={providerIcons[selected].path} /></svg></span>
{@render providerLogo(selected, true)}
<div><h4>{providerLabel(selected)}</h4><p>{providerDescription(selected)}</p></div>
{#if selected === "azure-devops"}
<span class="integration-status" class:configured={isConfigured(selected)}><Building2 size={13} />{settings.azureDevOpsOrganizations.length} {isGerman ? "Orgas" : "orgs"}</span>
@@ -236,10 +247,12 @@
.integration-providers > button { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 10px; min-height: 64px; padding: 9px 10px; border: 1px solid var(--color-border-subtle); border-radius: 9px; color: var(--color-ink-dim); background: var(--app-settings-row-bg); text-align: left; }
.integration-providers > button:hover { color: var(--color-ink); border-color: var(--color-border); background: var(--color-surface-hover); }
.integration-providers > button.active { border-color: color-mix(in srgb, var(--color-accent) 34%, var(--color-border)); color: var(--color-ink); background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface-raised)); box-shadow: inset 2px 0 0 var(--color-accent); }
.provider-logo { display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid color-mix(in srgb, var(--provider-color) 34%, var(--color-border)); border-radius: 8px; color: var(--provider-color); background: color-mix(in srgb, var(--provider-color) 10%, transparent); }
.provider-logo svg { width: 17px; height: 17px; fill: currentColor; }
.provider-logo-large { width: 42px; height: 42px; border-radius: 10px; }
.provider-logo-large svg { width: 22px; height: 22px; }
.provider-logo { position:relative;display:grid;place-items:center;flex:0 0 38px;width:38px;height:38px;border:1px solid var(--color-border-subtle);border-radius:6px;color:var(--provider-color);background:var(--color-surface-raised); }
.provider-brand-icon { display:block;width:24px;height:24px;fill:currentColor; }
.provider-logo-large { width:46px;height:46px;flex-basis:46px; }
.provider-logo-large .provider-brand-icon { width:30px;height:30px; }
.provider-instance-badge { position:absolute;right:-3px;bottom:-3px;display:grid;place-items:center;width:16px;height:16px;border:1px solid var(--color-border-input);border-radius:3px;background:var(--app-dialog-bg);color:var(--color-ink-muted); }
:global(:root[data-theme="light"]) .provider-logo { --provider-gitea-ink:#527c24;--provider-azure-ink:#0078d4; }
.provider-copy { display: grid; min-width: 0; gap: 3px; }
.provider-copy strong { color: inherit; font-size: 11px; }
.provider-copy small { overflow: hidden; color: var(--color-ink-faint); font-size: 9px; text-overflow: ellipsis; white-space: nowrap; }