feat: install instruction inside web app

This commit is contained in:
3252a8
2026-05-22 13:58:34 +03:00
parent 8a38524774
commit 9e61a3d8a8
41 changed files with 8216 additions and 72 deletions
@@ -1,5 +1,5 @@
<script>
import { ChevronRight, Eye, EyeOff, Search, X } from "$components/ui/icons.js";
import { ChevronRight, Eye, EyeOff, FileText, Search, X } from "$components/ui/icons.js";
import * as UiIcons from "$components/ui/icons.js";
import { Accordion, Switch } from "$components/ui/primitives.js";
import Dialog from "$components/ui/dialog.svelte";
@@ -123,6 +123,17 @@
closeIconPicker();
}
async function handleJsonFile(field, event) {
const file = event?.currentTarget?.files?.[0];
if (!file) return;
try {
const text = await file.text();
settingsStore.markDirty(field.key, text);
} finally {
event.currentTarget.value = "";
}
}
function groupSectionFields(section) {
const groups = new Map();
for (const field of section.fields || []) {
@@ -164,6 +175,7 @@
notifications: "Уведомления",
support: "Поддержка",
devices: "Устройства",
subscription_guides: "Connection guides",
};
return adminText(`settings_section_${id}`, {}, map[id] || id);
}
@@ -315,6 +327,41 @@
value={valueFor(field) ?? ""}
oninput={(e) => settingsStore.markDirty(field.key, e.currentTarget.value)}
></textarea>
{:else if field.type === "json"}
<div class="admin-json-toolbar">
<input
id={"json-file-" + field.key}
class="admin-json-file-input"
type="file"
accept="application/json,.json"
onchange={(event) => handleJsonFile(field, event)}
/>
<label
class="admin-btn admin-btn-sm admin-btn-ghost admin-json-upload"
for={"json-file-" + field.key}
>
<FileText size={13} />
{at("settings_json_upload", {}, "Load .json")}
</label>
{#if valueFor(field)}
<AdminButton
size="sm"
variant="ghost"
onclick={() => settingsStore.markDirty(field.key, "")}
>
<X size={12} />
{at("clear", {}, "Clear")}
</AdminButton>
{/if}
</div>
<textarea
class="admin-setting-textarea admin-setting-json-textarea"
rows="10"
spellcheck="false"
placeholder={fieldPlaceholderText(field)}
value={valueFor(field) ?? ""}
oninput={(e) => settingsStore.markDirty(field.key, e.currentTarget.value)}
></textarea>
{:else if field.secret}
<input
class="input"