Files
GitLite/src/lib/components/AppSettingsDialog.svelte
T
Christoph Brandau cae8390b54 feat(telemetry): Implement structured telemetry logging and reporting
Adds comprehensive client-side telemetry capabilities for usage, errors, and performance metrics. This includes integrating OpenTelemetry standards into both the frontend (Svelte) and backend (Tauri/Rust) layers to capture events, spans, and system resource utilization.

The implementation ensures that all collected data is privacy-filtered by design, explicitly excluding sensitive information like repository paths, credentials, source code, or email addresses from being logged.

- Updates README with detailed SigNoz telemetry guide
- Adds process metrics collection (CPU/Memory) in Rust backend
- Exposes `setTelemetryEnabled` state management to the frontend
2026-07-21 23:40:39 +02:00

143 lines
5.7 KiB
Svelte

<script lang="ts">
import { Check, Languages, RefreshCw, Settings, X } from "@lucide/svelte";
import type { AnalyticsSettings, AppLanguage, AppTheme } from "../types";
interface Props {
analytics: AnalyticsSettings;
theme: AppTheme;
language: AppLanguage;
autoRefresh: boolean;
onSave: (settings: AnalyticsSettings, theme: AppTheme, language: AppLanguage, autoRefresh: boolean) => void;
onClose: () => void;
}
let { analytics, theme = "system", language = "en", autoRefresh = true, onSave = () => {}, onClose = () => {} }: Props = $props();
let analyticsEnabled = $state(true);
let selectedTheme = $state<AppTheme>("system");
let selectedLanguage = $state<AppLanguage>("en");
let autoRefreshEnabled = $state(true);
const isGerman = $derived(selectedLanguage === "de");
$effect(() => {
analyticsEnabled = analytics.enabled;
selectedTheme = theme;
selectedLanguage = language;
autoRefreshEnabled = autoRefresh;
});
function save() {
onSave({
...analytics,
enabled: analyticsEnabled,
noticeSeen: true,
}, selectedTheme, selectedLanguage, autoRefreshEnabled);
}
</script>
<div class="dialog-backdrop" role="presentation">
<div class="dialog app-settings-dialog" role="dialog" aria-modal="true" aria-label={isGerman ? "Einstellungen" : "Settings"} tabindex="-1">
<header class="dialog-header">
<div>
<span class="eyebrow">Gitty</span>
<h2 class="dialog-title">{isGerman ? "Einstellungen" : "Settings"}</h2>
</div>
<button class="dialog-close" type="button" onclick={onClose} title={isGerman ? "Schließen" : "Close"}>
<X size={18} aria-hidden="true" />
</button>
</header>
<form class="app-settings-form" onsubmit={(event) => { event.preventDefault(); save(); }}>
<section class="settings-section">
<header>
<Settings size={16} aria-hidden="true" />
<div>
<span class="eyebrow">{isGerman ? "Darstellung" : "Appearance"}</span>
<h3>{isGerman ? "Farbschema" : "Theme"}</h3>
</div>
</header>
<div class="settings-segmented" role="radiogroup" aria-label={isGerman ? "Farbschema" : "Theme"}>
<label class:active={selectedTheme === "system"}>
<input type="radio" bind:group={selectedTheme} value="system" />
<span>System</span>
</label>
<label class:active={selectedTheme === "light"}>
<input type="radio" bind:group={selectedTheme} value="light" />
<span>{isGerman ? "Hell" : "Light"}</span>
</label>
<label class:active={selectedTheme === "dark"}>
<input type="radio" bind:group={selectedTheme} value="dark" />
<span>{isGerman ? "Dunkel" : "Dark"}</span>
</label>
</div>
</section>
<section class="settings-section">
<header>
<RefreshCw size={16} aria-hidden="true" />
<div>
<span class="eyebrow">Repository</span>
<h3>{isGerman ? "Automatische Aktualisierung" : "Auto refresh"}</h3>
</div>
</header>
<label class="settings-toggle-row">
<input type="checkbox" bind:checked={autoRefreshEnabled} />
<span>
<strong>{isGerman ? "Repositories automatisch aktualisieren" : "Refresh repositories automatically"}</strong>
<small>{isGerman ? "Aktualisiert Arbeitsbereich, Branch-Status und Remotes regelmäßig im Hintergrund." : "Periodically refreshes the working tree, branch status, and remotes in the background."}</small>
</span>
</label>
</section>
<section class="settings-section">
<header>
<Languages size={16} aria-hidden="true" />
<div>
<span class="eyebrow">{isGerman ? "Sprache" : "Language"}</span>
<h3>{isGerman ? "App-Sprache" : "App language"}</h3>
</div>
</header>
<div class="settings-segmented settings-language" role="radiogroup" aria-label={isGerman ? "App-Sprache" : "App language"}>
<label class:active={selectedLanguage === "en"}>
<input type="radio" bind:group={selectedLanguage} value="en" />
<span>EN · English</span>
</label>
<label class:active={selectedLanguage === "de"}>
<input type="radio" bind:group={selectedLanguage} value="de" />
<span>DE · Deutsch</span>
</label>
</div>
</section>
<section class="settings-section">
<header>
<Settings size={16} aria-hidden="true" />
<div>
<span class="eyebrow">Analytics</span>
<h3>{isGerman ? "Anonyme Nutzungsanalyse" : "Anonymous usage analytics"}</h3>
</div>
</header>
<label class="settings-toggle-row">
<input type="checkbox" bind:checked={analyticsEnabled} />
<span>
<strong>{isGerman ? "Anonyme Analytics und Fehlerberichte erlauben" : "Allow anonymous analytics and error reports"}</strong>
<small>{isGerman ? "Es werden keine Repository-Pfade, Remotes, Branches, Commit-Nachrichten, Dateinamen, Diffs, Zugangsdaten oder Code übertragen." : "No repository paths, remotes, branches, commit messages, file names, diffs, credentials, or code are sent."}</small>
</span>
</label>
</section>
<div class="new-branch-actions">
<button class="btn-secondary" type="button" onclick={onClose}>{isGerman ? "Abbrechen" : "Cancel"}</button>
<button class="btn-primary" type="submit">
<Check size={16} aria-hidden="true" />
{isGerman ? "Speichern" : "Save"}
</button>
</div>
</form>
</div>
</div>