fix: persist quick win reorder changes
This commit is contained in:
@@ -351,13 +351,18 @@ Der ausgegebene `VAPID_PRIVATE_KEY` ist bereits `.env`-freundlich mit escaped Ne
|
||||
- Quick-Wins als gemeinsames Team-Feature ausgebaut
|
||||
- neuer Optionen-Tab zum Anlegen und Verwalten gemeinsamer Quick-Wins
|
||||
- bestehende Quick-Wins in den Optionen direkt bearbeitbar gemacht
|
||||
- Quick-Win-Reihenfolge per Drag & Drop ergänzt und Speichern der Sortierung in den Optionen stabilisiert
|
||||
- Plus-Dialog von Einzelkarten auf kompakte auswählbare Quick-Win-Chips umgestellt
|
||||
- mehrere Quick-Wins lassen sich gesammelt als erledigt speichern
|
||||
- „Sonstiges“ blendet Titel und Aufwand jetzt nur bei Auswahl ein
|
||||
- neue Aufwand-Stufe `super aufwendig`
|
||||
- Quick-Win-Popup visuell mit übernommenem Sparkles-Icon aus `heinz.marketing` aufgewertet
|
||||
- gemeinsame Aufgaben für zwei Personen mit halbierten Punkten pro Person ergänzt
|
||||
- Aufgabenstatus in `morgen fällig`, `übermorgen fällig` und `bald fällig` feiner aufgeteilt
|
||||
- Aufgaben können jetzt von allen Nutzern direkt gelöscht werden
|
||||
- Kalenderdarstellung für lange deutsche Begriffe und Namen bei der Worttrennung nachgeschärft
|
||||
- deutsche Silbentrennung serverseitig vorbereitet, mit optionalem `pyphen`-Fallback ohne Startfehler im lokalen Dev-Setup
|
||||
- mobile Layouts für Aufgabenkarten, Bearbeiten-Ansicht und Quick-Win-Verwaltung weiter verdichtet und ausgerichtet
|
||||
- Footer auf Versionslink, Herkunftshinweis und `hnz.io`-Verweis umgebaut
|
||||
- Cloudron-Version auf `0.6.5` angehoben
|
||||
|
||||
|
||||
@@ -274,8 +274,11 @@ def update_quick_win(quick_win_id: int):
|
||||
@login_required
|
||||
@csrf.exempt
|
||||
def reorder_quick_wins():
|
||||
payload = request.get_json(silent=True) or {}
|
||||
payload = request.get_json(silent=True)
|
||||
if payload is not None:
|
||||
raw_ids = payload.get("ids", [])
|
||||
else:
|
||||
raw_ids = request.form.get("ids", "").split(",")
|
||||
ordered_ids = [int(item) for item in raw_ids if str(item).isdigit()]
|
||||
|
||||
quick_wins = QuickWin.query.filter_by(active=True).all()
|
||||
@@ -292,8 +295,12 @@ def reorder_quick_wins():
|
||||
quick_win.sort_order = offset
|
||||
|
||||
db.session.commit()
|
||||
if payload is not None:
|
||||
return jsonify({"ok": True})
|
||||
|
||||
flash("Die Quick-Win-Reihenfolge wurde gespeichert.", "success")
|
||||
return redirect(url_for("settings.quick_wins"))
|
||||
|
||||
|
||||
@bp.route("/users/<int:user_id>/toggle-admin", methods=["POST"])
|
||||
@login_required
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
const currentUserId = document.body.dataset.currentUserId;
|
||||
const currentUserName = document.body.dataset.currentUserName;
|
||||
const quickWinSortList = document.querySelector("[data-quick-win-sort-list]");
|
||||
const quickWinSortToken = document.getElementById("quickWinSortToken");
|
||||
const quickWinSortIds = document.getElementById("quickWinSortIds");
|
||||
const quickWinSortSave = document.getElementById("quickWinSortSave");
|
||||
const quickWinToggleButtons = document.querySelectorAll("[data-quick-win-toggle]");
|
||||
let draggedQuickWin = null;
|
||||
@@ -123,22 +123,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function persistQuickWinSort() {
|
||||
if (!quickWinSortList || !quickWinSortToken) {
|
||||
function syncQuickWinSortIds() {
|
||||
if (!quickWinSortList || !quickWinSortIds) {
|
||||
return;
|
||||
}
|
||||
const ids = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")]
|
||||
.map((item) => item.dataset.quickWinSortItem)
|
||||
.filter(Boolean);
|
||||
|
||||
await fetch("/settings/quick-wins/reorder", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": quickWinSortToken.value,
|
||||
},
|
||||
body: JSON.stringify({ ids }),
|
||||
});
|
||||
quickWinSortIds.value = ids.join(",");
|
||||
}
|
||||
|
||||
function setQuickWinSortDirty(isDirty) {
|
||||
@@ -149,6 +141,7 @@
|
||||
}
|
||||
|
||||
if (quickWinSortList) {
|
||||
syncQuickWinSortIds();
|
||||
setQuickWinSortDirty(false);
|
||||
|
||||
quickWinSortList.querySelectorAll("[data-quick-win-sort-item]").forEach((item) => {
|
||||
@@ -180,25 +173,12 @@
|
||||
} else {
|
||||
item.before(draggedQuickWin);
|
||||
}
|
||||
syncQuickWinSortIds();
|
||||
setQuickWinSortDirty(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (quickWinSortSave) {
|
||||
quickWinSortSave.addEventListener("click", async () => {
|
||||
if (!quickWinSortDirty) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await persistQuickWinSort();
|
||||
setQuickWinSortDirty(false);
|
||||
} catch (error) {
|
||||
console.error("Quick-Win-Sortierung konnte nicht gespeichert werden", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
quickWinToggleButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const targetId = button.dataset.target;
|
||||
|
||||
@@ -37,9 +37,12 @@
|
||||
<p class="eyebrow">Direkt sichtbar</p>
|
||||
<h2>Aktive Quick-Wins bearbeiten</h2>
|
||||
<p class="muted">Per Drag & Drop kannst du die Reihenfolge festlegen, die später auch bei den Quick-Win-Chips erscheint.</p>
|
||||
<input type="hidden" id="quickWinSortToken" value="{{ csrf_token() }}">
|
||||
<form method="post" action="{{ url_for('settings.reorder_quick_wins') }}" id="quickWinSortForm">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="ids" id="quickWinSortIds" value="{{ quick_wins|map(attribute='id')|join(',') }}">
|
||||
</form>
|
||||
<div class="quick-win-list__toolbar">
|
||||
<button type="button" class="button button--secondary" id="quickWinSortSave" disabled>Reihenfolge speichern</button>
|
||||
<button type="submit" class="button button--secondary" id="quickWinSortSave" form="quickWinSortForm" disabled>Reihenfolge speichern</button>
|
||||
</div>
|
||||
<div class="quick-win-list" data-quick-win-sort-list>
|
||||
{% for quick_win in quick_wins %}
|
||||
|
||||
Reference in New Issue
Block a user