visual fixes
This commit is contained in:
+2
-1
@@ -10,4 +10,5 @@ db/pgsql/*
|
||||
db/shopping.db
|
||||
*.swp
|
||||
version.txt
|
||||
deploy/varnish/default.vcl
|
||||
deploy/varnish/default.vcl
|
||||
*.zip
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import zipfile
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_git_command(args, repo_path: Path) -> bytes:
|
||||
result = subprocess.run(
|
||||
["git", *args],
|
||||
cwd=repo_path,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
)
|
||||
return result.stdout
|
||||
|
||||
|
||||
def get_files_to_archive(repo_path: Path) -> list[str]:
|
||||
output = run_git_command(
|
||||
["ls-files", "--cached", "--others", "--exclude-standard", "-z"],
|
||||
repo_path,
|
||||
)
|
||||
files = output.decode("utf-8", errors="surrogateescape").split("\0")
|
||||
return [f for f in files if f]
|
||||
|
||||
|
||||
def make_zip(repo_path: Path, output_zip: Path) -> None:
|
||||
files = get_files_to_archive(repo_path)
|
||||
|
||||
output_zip = output_zip.resolve()
|
||||
if output_zip.exists():
|
||||
output_zip.unlink()
|
||||
|
||||
with zipfile.ZipFile(output_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
|
||||
for rel_path in files:
|
||||
abs_path = repo_path / rel_path
|
||||
|
||||
if not abs_path.exists():
|
||||
continue
|
||||
|
||||
if abs_path.resolve() == output_zip:
|
||||
continue
|
||||
|
||||
zf.write(abs_path, arcname=rel_path)
|
||||
|
||||
print(f"Utworzono archiwum: {output_zip}")
|
||||
print(f"Added files: {len(files)}")
|
||||
|
||||
|
||||
def main():
|
||||
repo_path = Path.cwd()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
output_zip = Path(sys.argv[1])
|
||||
else:
|
||||
output_zip = repo_path / f"{repo_path.name}.zip"
|
||||
|
||||
try:
|
||||
run_git_command(["rev-parse", "--show-toplevel"], repo_path)
|
||||
except subprocess.CalledProcessError:
|
||||
print("Error: this directory is not a Git repository.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
make_zip(repo_path, output_zip)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -139,6 +139,13 @@ function setupList(listId, username) {
|
||||
note: ''
|
||||
};
|
||||
|
||||
// Note: store newly added items locally so later edits do not depend on a full page refresh.
|
||||
if (Array.isArray(window.currentItems)) {
|
||||
window.currentItems.push(item);
|
||||
} else {
|
||||
window.currentItems = [item];
|
||||
}
|
||||
|
||||
const isOwnFreshShareItem = Boolean(
|
||||
window.IS_SHARE &&
|
||||
data.added_by &&
|
||||
@@ -216,22 +223,40 @@ function setupList(listId, username) {
|
||||
});
|
||||
|
||||
socket.on('item_edited', data => {
|
||||
const idx = window.currentItems.findIndex(i => i.id === data.item_id);
|
||||
if (idx !== -1) {
|
||||
window.currentItems[idx].name = data.new_name;
|
||||
window.currentItems[idx].quantity = data.new_quantity;
|
||||
const itemId = Number(data.item_id);
|
||||
const oldItem = document.getElementById(`item-${itemId}`);
|
||||
const currentItems = Array.isArray(window.currentItems) ? window.currentItems : [];
|
||||
const idx = currentItems.findIndex(item => Number(item.id) === itemId);
|
||||
const cachedItem = idx !== -1 ? currentItems[idx] : {};
|
||||
|
||||
const newItem = renderItem(window.currentItems[idx], window.IS_SHARE);
|
||||
const oldItem = document.getElementById(`item-${data.item_id}`);
|
||||
if (oldItem && newItem) {
|
||||
oldItem.replaceWith(newItem);
|
||||
}
|
||||
// Note: keep the edited item visible immediately, even when the local list cache is stale.
|
||||
const updatedItem = {
|
||||
...cachedItem,
|
||||
id: itemId,
|
||||
name: data.new_name,
|
||||
quantity: data.new_quantity,
|
||||
purchased: oldItem ? oldItem.classList.contains('bg-success') : !!cachedItem.purchased,
|
||||
not_purchased: oldItem ? oldItem.classList.contains('bg-warning') : !!cachedItem.not_purchased,
|
||||
not_purchased_reason: cachedItem.not_purchased_reason || '',
|
||||
note: cachedItem.note || ''
|
||||
};
|
||||
|
||||
if (idx !== -1) {
|
||||
currentItems[idx] = updatedItem;
|
||||
window.currentItems = currentItems;
|
||||
}
|
||||
|
||||
if (oldItem) {
|
||||
oldItem.replaceWith(renderItem(updatedItem, window.IS_SHARE));
|
||||
} else if (window.LIST_ID) {
|
||||
socket.emit('request_full_list', { list_id: window.LIST_ID });
|
||||
}
|
||||
|
||||
showToast(`Zaktualizowano produkt: ${data.new_name} (x${data.new_quantity})`, 'success');
|
||||
|
||||
updateProgressBar();
|
||||
toggleEmptyPlaceholder();
|
||||
applyHidePurchased();
|
||||
});
|
||||
|
||||
// --- WAŻNE: zapisz dane do reconnect ---
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
new TomSelect("#categories", {
|
||||
const categoriesSelect = document.querySelector("#categories");
|
||||
|
||||
if (!categoriesSelect || typeof TomSelect === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
new TomSelect(categoriesSelect, {
|
||||
plugins: ['remove_button'],
|
||||
maxItems: 1,
|
||||
placeholder: 'Wybierz jedną kategorie...',
|
||||
placeholder: 'Wybierz jedną kategorię...',
|
||||
create: false,
|
||||
dropdownParent: 'body',
|
||||
sortField: {
|
||||
field: "text",
|
||||
direction: "asc"
|
||||
|
||||
Reference in New Issue
Block a user