fix(planka): propagation erreurs Planka + noms étiquettes + position dans saveCard
Deploy HouseHub / deploy (push) Successful in 2s
Deploy HouseHub / deploy (push) Successful in 2s
- update_card: transmet position à Planka + retourne erreur réelle si Planka rejette - saveCard: n'envoie listId que si changé (position requise par Planka), sinon nom/desc/dueDate seul - Labels: affiche le nom en texte dans le badge coloré (comme Planka) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5828d1796d
commit
e770ccf22b
@@ -127,12 +127,14 @@ if ($action === 'update_card') {
|
|||||||
$id = $_GET['id'] ?? null; if (!$id) tErr('ID manquant');
|
$id = $_GET['id'] ?? null; if (!$id) tErr('ID manquant');
|
||||||
$d = tBody();
|
$d = tBody();
|
||||||
$payload = [];
|
$payload = [];
|
||||||
if (isset($d['name'])) $payload['name'] = $d['name'];
|
if (isset($d['name'])) $payload['name'] = $d['name'];
|
||||||
if (isset($d['description'])) $payload['description'] = $d['description'];
|
if (isset($d['description'])) $payload['description'] = $d['description'];
|
||||||
if (array_key_exists('dueDate', $d)) $payload['dueDate'] = $d['dueDate'];
|
if (array_key_exists('dueDate', $d)) $payload['dueDate'] = $d['dueDate'];
|
||||||
if (isset($d['listId'])) $payload['listId'] = $d['listId'];
|
if (isset($d['listId'])) $payload['listId'] = $d['listId'];
|
||||||
|
if (isset($d['position'])) $payload['position'] = (float)$d['position'];
|
||||||
$resp = planka_api('PATCH', '/api/cards/' . $id, $payload, $token);
|
$resp = planka_api('PATCH', '/api/cards/' . $id, $payload, $token);
|
||||||
tOk($resp['item'] ?? []);
|
if (empty($resp['item'])) tErr($resp['message'] ?? ($resp['problems'][0] ?? 'Planka a rejeté la mise à jour'), 502);
|
||||||
|
tOk($resp['item']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($action === 'delete_card') {
|
if ($action === 'delete_card') {
|
||||||
|
|||||||
@@ -166,10 +166,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pk-label {
|
.pk-label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 20px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: .72rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-shadow: 0 1px 2px rgba(0,0,0,.3);
|
||||||
|
min-width: 36px;
|
||||||
|
}
|
||||||
|
.pk-label:empty {
|
||||||
height: 6px;
|
height: 6px;
|
||||||
width: 36px;
|
width: 36px;
|
||||||
border-radius: 3px;
|
padding: 0;
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pk-card-name {
|
.pk-card-name {
|
||||||
|
|||||||
+15
-8
@@ -218,7 +218,7 @@ function renderCard(card, prevCard) {
|
|||||||
const labels = (state.cardLabels || []).filter(cl => cl.cardId === card.id).map(cl => {
|
const labels = (state.cardLabels || []).filter(cl => cl.cardId === card.id).map(cl => {
|
||||||
const lbl = (state.labels || []).find(l => l.id === cl.labelId);
|
const lbl = (state.labels || []).find(l => l.id === cl.labelId);
|
||||||
if (!lbl) return '';
|
if (!lbl) return '';
|
||||||
return `<span class="pk-label pk-label-color--${lbl.color || 'morning-sky'}" title="${esc(lbl.name || '')}"></span>`;
|
return `<span class="pk-label pk-label-color--${lbl.color || 'morning-sky'}">${esc(lbl.name || '')}</span>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
const cardTasks = (state.tasks || []).filter(t => t.cardId === card.id);
|
const cardTasks = (state.tasks || []).filter(t => t.cardId === card.id);
|
||||||
const doneCount = cardTasks.filter(t => t.isCompleted).length;
|
const doneCount = cardTasks.filter(t => t.isCompleted).length;
|
||||||
@@ -296,22 +296,29 @@ function closeCardModal() {
|
|||||||
|
|
||||||
async function saveCard() {
|
async function saveCard() {
|
||||||
if (!editingCard) return;
|
if (!editingCard) return;
|
||||||
const name = document.getElementById('pk-card-name').value.trim();
|
const name = document.getElementById('pk-card-name').value.trim();
|
||||||
if (!name) { showToast('Titre requis', 'error'); return; }
|
if (!name) { showToast('Titre requis', 'error'); return; }
|
||||||
const due = document.getElementById('pk-card-due').value;
|
const due = document.getElementById('pk-card-due').value;
|
||||||
const body = {
|
const listId = document.getElementById('pk-card-list').value;
|
||||||
|
const body = {
|
||||||
name,
|
name,
|
||||||
description: document.getElementById('pk-card-desc').value,
|
description: document.getElementById('pk-card-desc').value,
|
||||||
dueDate: due ? due + 'T00:00:00.000Z' : null,
|
dueDate: due ? due + 'T00:00:00.000Z' : null,
|
||||||
listId: document.getElementById('pk-card-list').value,
|
|
||||||
};
|
};
|
||||||
|
// Planka requires position whenever listId is sent — only include if list changed
|
||||||
|
if (listId !== editingCard.listId) {
|
||||||
|
body.listId = listId;
|
||||||
|
const targetCards = state.cards.filter(c => c.listId === listId);
|
||||||
|
const maxPos = targetCards.reduce((m, c) => Math.max(m, c.position || 0), 0);
|
||||||
|
body.position = maxPos + 65535;
|
||||||
|
}
|
||||||
const res = await apiFetch('update_card', { id: editingCard.id }, 'PATCH', body);
|
const res = await apiFetch('update_card', { id: editingCard.id }, 'PATCH', body);
|
||||||
if (!res.ok) { showToast('Erreur: ' + res.error, 'error'); return; }
|
if (!res.ok) { showToast('Erreur : ' + (res.error || 'sauvegarde impossible'), 'error'); return; }
|
||||||
const idx = state.cards.findIndex(c => c.id === editingCard.id);
|
const idx = state.cards.findIndex(c => c.id === editingCard.id);
|
||||||
if (idx >= 0) state.cards[idx] = { ...state.cards[idx], ...res.data };
|
if (idx >= 0) state.cards[idx] = { ...state.cards[idx], ...res.data, listId: listId };
|
||||||
closeCardModal();
|
closeCardModal();
|
||||||
renderBoard();
|
renderBoard();
|
||||||
showToast('Carte enregistrée');
|
showToast('Carte enregistrée ✓');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteCard() {
|
async function deleteCard() {
|
||||||
|
|||||||
Reference in New Issue
Block a user