feat(integrations): support GitHub repositories and enhance repo browser UI
Add GitHub repository support to integrations and update related tests. Implement server-side GitHub API calls and normalize GitHub base URLs. Improve the repository browser UI with compact tabs and updated icons. Add a custom, accessible scrollbar with pointer and keyboard support. - Add paging, auth headers, and error handling when listing GitHub repos. - Default GitHub token username to "x-access-token" when saving credentials. - Introduce compact repo tab styles, new icons, and a draggable scrollbar.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { Building2, CheckCircle2, CircleDashed, Eye, EyeOff, KeyRound, Plus, Server, Trash2 } from "@lucide/svelte";
|
||||
import { siGitea, siGitlab, type SimpleIcon } from "simple-icons";
|
||||
import { siGitea, siGithub, siGitlab, type SimpleIcon } from "simple-icons";
|
||||
import { gitIntegrationProviders, organizationNameFromUrl, providerLabel } from "../integrations";
|
||||
import type { AppLanguage, AzureDevOpsOrganization, GitIntegrationConfig, GitIntegrationProvider, GitIntegrationSecretUpdate, GitIntegrationSettings } from "../types";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
}
|
||||
|
||||
let { language, settings, onChange, onSecretsChange }: Props = $props();
|
||||
let selected = $state<GitIntegrationProvider>("gitlab");
|
||||
let selected = $state<GitIntegrationProvider>("github");
|
||||
let selectedAzureOrganizationId = $state("");
|
||||
let tokenValues = $state<Record<string, string>>({});
|
||||
let secretUpdates = $state<Record<string, GitIntegrationSecretUpdate>>({});
|
||||
@@ -27,15 +27,19 @@
|
||||
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",
|
||||
};
|
||||
const providerIcons: Record<GitIntegrationProvider, SimpleIcon> = { gitlab: siGitlab, "gitlab-self-hosted": siGitlab, "azure-devops": azureDevOpsIcon, gitea: siGitea };
|
||||
const providerIcons: Record<GitIntegrationProvider, SimpleIcon> = { github: siGithub, gitlab: siGitlab, "gitlab-self-hosted": siGitlab, "azure-devops": azureDevOpsIcon, gitea: siGitea };
|
||||
|
||||
function providerDescription(provider: GitIntegrationProvider): string {
|
||||
const descriptions = isGerman
|
||||
? { gitlab: "Cloud-Konto auf gitlab.com", "gitlab-self-hosted": "Eigene GitLab-Instanz", "azure-devops": "Mehrere Organisationen", gitea: "Cloud- oder eigene Instanz" }
|
||||
: { gitlab: "Cloud account on gitlab.com", "gitlab-self-hosted": "Your own GitLab instance", "azure-devops": "Multiple organizations", gitea: "Cloud or self-hosted instance" };
|
||||
? { github: "Konto auf github.com", gitlab: "Cloud-Konto auf gitlab.com", "gitlab-self-hosted": "Eigene GitLab-Instanz", "azure-devops": "Mehrere Organisationen", gitea: "Cloud- oder eigene Instanz" }
|
||||
: { github: "Cloud account on github.com", gitlab: "Cloud account on gitlab.com", "gitlab-self-hosted": "Your own GitLab instance", "azure-devops": "Multiple organizations", gitea: "Cloud or self-hosted instance" };
|
||||
return descriptions[provider];
|
||||
}
|
||||
|
||||
function providerColor(provider: GitIntegrationProvider): string {
|
||||
return provider === "github" ? "var(--color-ink)" : `#${providerIcons[provider].hex}`;
|
||||
}
|
||||
|
||||
function secretId(provider: GitIntegrationProvider, accountId?: string): string {
|
||||
return accountId ? `${provider}:${accountId}` : provider;
|
||||
}
|
||||
@@ -150,6 +154,7 @@
|
||||
|
||||
function baseUrlPlaceholder(): string {
|
||||
if (selected === "azure-devops") return "https://dev.azure.com/meine-organisation";
|
||||
if (selected === "github") return "https://github.com";
|
||||
if (selected === "gitlab") return "https://gitlab.com";
|
||||
if (selected === "gitlab-self-hosted") return "https://gitlab.example.com";
|
||||
return "https://gitea.example.com";
|
||||
@@ -160,7 +165,7 @@
|
||||
<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:#${providerIcons[provider].hex}`}><svg viewBox="0 0 24 24" aria-hidden="true"><path d={providerIcons[provider].path} /></svg></span>
|
||||
<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>
|
||||
<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>
|
||||
@@ -169,7 +174,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:#${providerIcons[selected].hex}`}><svg viewBox="0 0 24 24" aria-hidden="true"><path d={providerIcons[selected].path} /></svg></span>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user