Compare commits
2 Commits
d1ffb806bd
...
557e9319d6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
557e9319d6 | ||
|
|
d6e7df8ada |
@ -51,9 +51,11 @@ const BACKUP_LOC_FIELD_DEFS = {
|
|||||||
KEEP_YEARLY: { title: 'Keep yearly', description: 'One snapshot per year for this many years.' }
|
KEEP_YEARLY: { title: 'Keep yearly', description: 'One snapshot per year for this many years.' }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type leads each list: it's the choice that shapes the rest of the form, so
|
// Fallback for the per-type field schema. The live source is the generator-
|
||||||
// it renders before the friendly Name. ENGINE stays here but is filtered into
|
// emitted data/backup/generated/schema.json (loaded into this.locSchema and
|
||||||
// the Advanced tab by locFieldGroups.
|
// read via locFieldsForType); this map is only used if that fetch fails.
|
||||||
|
// Type leads each list (it shapes the rest of the form); ENGINE stays in the
|
||||||
|
// list but locFieldGroups folds it into the Advanced tab.
|
||||||
const BACKUP_LOC_FIELDS_BY_TYPE = {
|
const BACKUP_LOC_FIELDS_BY_TYPE = {
|
||||||
local: ['TYPE', 'NAME', 'ENGINE', 'PATH_MODE', 'PATH', 'APPEND_ONLY'],
|
local: ['TYPE', 'NAME', 'ENGINE', 'PATH_MODE', 'PATH', 'APPEND_ONLY'],
|
||||||
sftp: ['TYPE', 'NAME', 'ENGINE', 'SSH_USER', 'SSH_HOST', 'SSH_PORT', 'SSH_PATH', 'SSH_AUTH', 'SSH_PASS', 'URI', 'APPEND_ONLY'],
|
sftp: ['TYPE', 'NAME', 'ENGINE', 'SSH_USER', 'SSH_HOST', 'SSH_PORT', 'SSH_PATH', 'SSH_AUTH', 'SSH_PASS', 'URI', 'APPEND_ONLY'],
|
||||||
@ -286,13 +288,15 @@ class BackupPage {
|
|||||||
|
|
||||||
async refreshAll() {
|
async refreshAll() {
|
||||||
const ts = Date.now();
|
const ts = Date.now();
|
||||||
const [dashboard, locations] = await Promise.all([
|
const [dashboard, locations, , schema] = await Promise.all([
|
||||||
this.fetchJson(`/data/backup/generated/dashboard.json?t=${ts}`),
|
this.fetchJson(`/data/backup/generated/dashboard.json?t=${ts}`),
|
||||||
this.fetchJson(`/data/backup/generated/locations.json?t=${ts}`),
|
this.fetchJson(`/data/backup/generated/locations.json?t=${ts}`),
|
||||||
this.loadSystemConfigs()
|
this.loadSystemConfigs(),
|
||||||
|
this.fetchJson(`/data/backup/generated/schema.json?t=${ts}`)
|
||||||
]);
|
]);
|
||||||
this.dashboard = dashboard;
|
this.dashboard = dashboard;
|
||||||
this.locations = locations;
|
this.locations = locations;
|
||||||
|
this.locSchema = schema;
|
||||||
this.snapshotsByLoc = {};
|
this.snapshotsByLoc = {};
|
||||||
|
|
||||||
if (!this.engines.length) await this.loadEngines();
|
if (!this.engines.length) await this.loadEngines();
|
||||||
@ -1400,7 +1404,7 @@ class BackupPage {
|
|||||||
const idx = parseInt(modal.dataset.locIdx, 10);
|
const idx = parseInt(modal.dataset.locIdx, 10);
|
||||||
const loc = locOverride || (this.locations?.locations || []).find(l => l.idx === idx) || {};
|
const loc = locOverride || (this.locations?.locations || []).find(l => l.idx === idx) || {};
|
||||||
|
|
||||||
const suffixes = BACKUP_LOC_FIELDS_BY_TYPE[type] || BACKUP_LOC_FIELDS_BY_TYPE.local;
|
const suffixes = this.locFieldsForType(type);
|
||||||
container.innerHTML = this.renderLocFields(idx, suffixes, loc);
|
container.innerHTML = this.renderLocFields(idx, suffixes, loc);
|
||||||
this.tagFieldsForSave(container);
|
this.tagFieldsForSave(container);
|
||||||
}
|
}
|
||||||
@ -1494,9 +1498,18 @@ class BackupPage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ordered field list for a location type. Primary source is the generator-
|
||||||
|
emitted schema.json (this.locSchema); BACKUP_LOC_FIELDS_BY_TYPE is the
|
||||||
|
fallback if that file didn't load. */
|
||||||
|
locFieldsForType(type) {
|
||||||
|
return this.locSchema?.types?.[type]
|
||||||
|
|| BACKUP_LOC_FIELDS_BY_TYPE[type]
|
||||||
|
|| BACKUP_LOC_FIELDS_BY_TYPE.local;
|
||||||
|
}
|
||||||
|
|
||||||
/* Split a type's fields into the Connection tab vs the Advanced tab. */
|
/* Split a type's fields into the Connection tab vs the Advanced tab. */
|
||||||
locFieldGroups(idx, type) {
|
locFieldGroups(idx, type) {
|
||||||
const suffixes = BACKUP_LOC_FIELDS_BY_TYPE[type] || BACKUP_LOC_FIELDS_BY_TYPE.local;
|
const suffixes = this.locFieldsForType(type);
|
||||||
const connection = [];
|
const connection = [];
|
||||||
const advanced = [];
|
const advanced = [];
|
||||||
for (const suffix of suffixes) {
|
for (const suffix of suffixes) {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ cliHandleWebuiCommands()
|
|||||||
webuiGenerateBackupDashboard
|
webuiGenerateBackupDashboard
|
||||||
webuiGenerateBackupSnapshots "${options:-all}"
|
webuiGenerateBackupSnapshots "${options:-all}"
|
||||||
webuiGenerateBackupAppStatus
|
webuiGenerateBackupAppStatus
|
||||||
|
webuiGenerateBackupSchema
|
||||||
webuiGenerateBackupPasswords
|
webuiGenerateBackupPasswords
|
||||||
elif [ "$config_type" = "system" ]; then
|
elif [ "$config_type" = "system" ]; then
|
||||||
webuiSystemUpdate
|
webuiSystemUpdate
|
||||||
|
|||||||
51
scripts/webui/data/generators/backup/webui_backup_schema.sh
Normal file
51
scripts/webui/data/generators/backup/webui_backup_schema.sh
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Source of truth for the Locations editor form layout: which CFG_BACKUP_LOC_*
|
||||||
|
# fields apply to each backup location type, in render order. Emitted as
|
||||||
|
# data/backup/generated/schema.json so the frontend builds the form from data
|
||||||
|
# instead of a hardcoded map (it keeps a fallback only). ENGINE stays in the
|
||||||
|
# list — the frontend folds it into the Advanced tab via the per-field
|
||||||
|
# "advanced" flag from configs.json; this file is purely about applicability
|
||||||
|
# and order.
|
||||||
|
|
||||||
|
webuiGenerateBackupSchema()
|
||||||
|
{
|
||||||
|
local out_dir="$containers_dir/libreportal/frontend/data/backup/generated"
|
||||||
|
local out_file="$out_dir/schema.json"
|
||||||
|
sudo mkdir -p "$out_dir"
|
||||||
|
|
||||||
|
# "<type>|FIELD,FIELD,..." — order here is the form's render order.
|
||||||
|
local rows=(
|
||||||
|
"local|TYPE,NAME,ENGINE,PATH_MODE,PATH,APPEND_ONLY"
|
||||||
|
"sftp|TYPE,NAME,ENGINE,SSH_USER,SSH_HOST,SSH_PORT,SSH_PATH,SSH_AUTH,SSH_PASS,URI,APPEND_ONLY"
|
||||||
|
"rest|TYPE,NAME,ENGINE,URI,APPEND_ONLY"
|
||||||
|
"s3|TYPE,NAME,ENGINE,URI,S3_ACCESS_KEY,S3_SECRET_KEY,APPEND_ONLY"
|
||||||
|
"b2|TYPE,NAME,ENGINE,URI,B2_ACCOUNT_ID,B2_ACCOUNT_KEY,APPEND_ONLY"
|
||||||
|
"gs|TYPE,NAME,ENGINE,URI,APPEND_ONLY"
|
||||||
|
"azure|TYPE,NAME,ENGINE,URI,APPEND_ONLY"
|
||||||
|
"rclone|TYPE,NAME,ENGINE,URI,APPEND_ONLY"
|
||||||
|
)
|
||||||
|
|
||||||
|
local json="{\"generated_at\":\"$(date -Iseconds)\",\"types\":{"
|
||||||
|
local first=true row type fields f farr firstf
|
||||||
|
for row in "${rows[@]}"; do
|
||||||
|
type="${row%%|*}"
|
||||||
|
fields="${row#*|}"
|
||||||
|
$first || json+=","
|
||||||
|
first=false
|
||||||
|
json+="\"$type\":["
|
||||||
|
firstf=true
|
||||||
|
IFS=',' read -ra farr <<< "$fields"
|
||||||
|
for f in "${farr[@]}"; do
|
||||||
|
$firstf || json+=","
|
||||||
|
firstf=false
|
||||||
|
json+="\"$f\""
|
||||||
|
done
|
||||||
|
json+="]"
|
||||||
|
done
|
||||||
|
json+="}}"
|
||||||
|
|
||||||
|
echo "$json" | sudo tee "$out_file" >/dev/null
|
||||||
|
createTouch "$out_file" "$docker_install_user" "silent"
|
||||||
|
isSuccessful "Backup location schema regenerated"
|
||||||
|
}
|
||||||
@ -82,7 +82,7 @@ webuiLibrePortalUpdate() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate Backup locations / snapshots / engines / dashboards
|
# Generate Backup locations / snapshots / engines / dashboards
|
||||||
local result=$(webuiGenerateBackupLocations && webuiGenerateBackupDashboard && webuiGenerateBackupSnapshots all && webuiGenerateBackupAppStatus && webuiGenerateBackupEngines && webuiGenerateBackupPasswords)
|
local result=$(webuiGenerateBackupLocations && webuiGenerateBackupDashboard && webuiGenerateBackupSnapshots all && webuiGenerateBackupAppStatus && webuiGenerateBackupEngines && webuiGenerateBackupSchema && webuiGenerateBackupPasswords)
|
||||||
checkSuccess "Refreshed backup dashboard data..."
|
checkSuccess "Refreshed backup dashboard data..."
|
||||||
|
|
||||||
# Sync app icons
|
# Sync app icons
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user