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
|
- Quick-Wins als gemeinsames Team-Feature ausgebaut
|
||||||
- neuer Optionen-Tab zum Anlegen und Verwalten gemeinsamer Quick-Wins
|
- neuer Optionen-Tab zum Anlegen und Verwalten gemeinsamer Quick-Wins
|
||||||
- bestehende Quick-Wins in den Optionen direkt bearbeitbar gemacht
|
- 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
|
- Plus-Dialog von Einzelkarten auf kompakte auswählbare Quick-Win-Chips umgestellt
|
||||||
- mehrere Quick-Wins lassen sich gesammelt als erledigt speichern
|
- mehrere Quick-Wins lassen sich gesammelt als erledigt speichern
|
||||||
- „Sonstiges“ blendet Titel und Aufwand jetzt nur bei Auswahl ein
|
- „Sonstiges“ blendet Titel und Aufwand jetzt nur bei Auswahl ein
|
||||||
- neue Aufwand-Stufe `super aufwendig`
|
- neue Aufwand-Stufe `super aufwendig`
|
||||||
- Quick-Win-Popup visuell mit übernommenem Sparkles-Icon aus `heinz.marketing` aufgewertet
|
- 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
|
- 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
|
- 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
|
- Footer auf Versionslink, Herkunftshinweis und `hnz.io`-Verweis umgebaut
|
||||||
- Cloudron-Version auf `0.6.5` angehoben
|
- Cloudron-Version auf `0.6.5` angehoben
|
||||||
|
|
||||||
|
|||||||
@@ -274,8 +274,11 @@ def update_quick_win(quick_win_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@csrf.exempt
|
@csrf.exempt
|
||||||
def reorder_quick_wins():
|
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", [])
|
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()]
|
ordered_ids = [int(item) for item in raw_ids if str(item).isdigit()]
|
||||||
|
|
||||||
quick_wins = QuickWin.query.filter_by(active=True).all()
|
quick_wins = QuickWin.query.filter_by(active=True).all()
|
||||||
@@ -292,8 +295,12 @@ def reorder_quick_wins():
|
|||||||
quick_win.sort_order = offset
|
quick_win.sort_order = offset
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
if payload is not None:
|
||||||
return jsonify({"ok": True})
|
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"])
|
@bp.route("/users/<int:user_id>/toggle-admin", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
const currentUserId = document.body.dataset.currentUserId;
|
const currentUserId = document.body.dataset.currentUserId;
|
||||||
const currentUserName = document.body.dataset.currentUserName;
|
const currentUserName = document.body.dataset.currentUserName;
|
||||||
const quickWinSortList = document.querySelector("[data-quick-win-sort-list]");
|
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 quickWinSortSave = document.getElementById("quickWinSortSave");
|
||||||
const quickWinToggleButtons = document.querySelectorAll("[data-quick-win-toggle]");
|
const quickWinToggleButtons = document.querySelectorAll("[data-quick-win-toggle]");
|
||||||
let draggedQuickWin = null;
|
let draggedQuickWin = null;
|
||||||
@@ -123,22 +123,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function persistQuickWinSort() {
|
function syncQuickWinSortIds() {
|
||||||
if (!quickWinSortList || !quickWinSortToken) {
|
if (!quickWinSortList || !quickWinSortIds) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ids = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")]
|
const ids = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")]
|
||||||
.map((item) => item.dataset.quickWinSortItem)
|
.map((item) => item.dataset.quickWinSortItem)
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
quickWinSortIds.value = ids.join(",");
|
||||||
await fetch("/settings/quick-wins/reorder", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-CSRFToken": quickWinSortToken.value,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ ids }),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setQuickWinSortDirty(isDirty) {
|
function setQuickWinSortDirty(isDirty) {
|
||||||
@@ -149,6 +141,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (quickWinSortList) {
|
if (quickWinSortList) {
|
||||||
|
syncQuickWinSortIds();
|
||||||
setQuickWinSortDirty(false);
|
setQuickWinSortDirty(false);
|
||||||
|
|
||||||
quickWinSortList.querySelectorAll("[data-quick-win-sort-item]").forEach((item) => {
|
quickWinSortList.querySelectorAll("[data-quick-win-sort-item]").forEach((item) => {
|
||||||
@@ -180,25 +173,12 @@
|
|||||||
} else {
|
} else {
|
||||||
item.before(draggedQuickWin);
|
item.before(draggedQuickWin);
|
||||||
}
|
}
|
||||||
|
syncQuickWinSortIds();
|
||||||
setQuickWinSortDirty(true);
|
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) => {
|
quickWinToggleButtons.forEach((button) => {
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("click", () => {
|
||||||
const targetId = button.dataset.target;
|
const targetId = button.dataset.target;
|
||||||
|
|||||||
@@ -37,9 +37,12 @@
|
|||||||
<p class="eyebrow">Direkt sichtbar</p>
|
<p class="eyebrow">Direkt sichtbar</p>
|
||||||
<h2>Aktive Quick-Wins bearbeiten</h2>
|
<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>
|
<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">
|
<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>
|
||||||
<div class="quick-win-list" data-quick-win-sort-list>
|
<div class="quick-win-list" data-quick-win-sort-list>
|
||||||
{% for quick_win in quick_wins %}
|
{% for quick_win in quick_wins %}
|
||||||
|
|||||||
Reference in New Issue
Block a user