Polish mobile shopping rows and stabilize backup archives
This commit is contained in:
+15
-3
@@ -52,13 +52,25 @@ def export_backup_archive(
|
||||
payload["tables"][table_name] = [dict(row) for row in rows]
|
||||
|
||||
uploads_root = Path(upload_folder)
|
||||
with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
archive.writestr("backup.json", json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
uploads_snapshot_dir = Path(tempfile.mkdtemp(prefix="nouri-backup-uploads-"))
|
||||
try:
|
||||
if uploads_root.exists():
|
||||
for file_path in uploads_root.rglob("*"):
|
||||
if not file_path.is_file():
|
||||
continue
|
||||
relative_path = file_path.relative_to(uploads_root)
|
||||
snapshot_path = uploads_snapshot_dir / relative_path
|
||||
snapshot_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(file_path, snapshot_path)
|
||||
|
||||
with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
archive.writestr("backup.json", json.dumps(payload, ensure_ascii=False, indent=2))
|
||||
for file_path in uploads_snapshot_dir.rglob("*"):
|
||||
if file_path.is_file():
|
||||
relative_path = file_path.relative_to(uploads_root)
|
||||
relative_path = file_path.relative_to(uploads_snapshot_dir)
|
||||
archive.write(file_path, f"uploads/{relative_path.as_posix()}")
|
||||
finally:
|
||||
shutil.rmtree(uploads_snapshot_dir, ignore_errors=True)
|
||||
|
||||
return archive_path, backup_name
|
||||
|
||||
|
||||
@@ -1356,6 +1356,18 @@ h3 {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.shopping-entry-check-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.shopping-entry-check-mark {
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.shopping-entry-close-form {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
@@ -1415,24 +1427,68 @@ h3 {
|
||||
|
||||
@media (max-width: 680px) {
|
||||
.shopping-entry-row {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto auto;
|
||||
align-items: center;
|
||||
gap: 0.7rem;
|
||||
}
|
||||
|
||||
.shopping-entry-open {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.shopping-entry-main {
|
||||
grid-template-columns: 56px minmax(0, 1fr);
|
||||
gap: 0.8rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.shopping-entry-visual,
|
||||
.shopping-entry-fallback {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.shopping-entry-copy {
|
||||
gap: 0.12rem;
|
||||
}
|
||||
|
||||
.shopping-entry-copy strong {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.shopping-entry-copy .muted {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shopping-entry-actions,
|
||||
.shopping-entry-actions form,
|
||||
.shopping-entry-actions button,
|
||||
.shopping-entry-close-form {
|
||||
width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.shopping-entry-check-button {
|
||||
min-width: 0;
|
||||
padding: 0.75rem 0.9rem;
|
||||
border-radius: 16px;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.shopping-entry-check-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shopping-entry-check-mark {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.shopping-entry-close {
|
||||
width: 100%;
|
||||
border-radius: 18px;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
min-width: 2.75rem;
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,10 @@
|
||||
<div class="shopping-entry-actions">
|
||||
<form method="post" action="{{ url_for('main.shopping_check', entry_id=entry.id) }}">
|
||||
{{ csrf_input() }}
|
||||
<button type="submit">Eingekauft</button>
|
||||
<button type="submit" class="shopping-entry-check-button">
|
||||
<span class="shopping-entry-check-mark" aria-hidden="true">✔</span>
|
||||
<span class="shopping-entry-check-label">Eingekauft</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{% if entry.can_edit %}
|
||||
|
||||
Reference in New Issue
Block a user