From 232a6b4238fdd07a1778d32de76f069a676420ef Mon Sep 17 00:00:00 2001 From: dv Date: Mon, 23 Mar 2026 22:38:53 +0300 Subject: [PATCH] sync2 vibe --- public/js/sse.js | 11 +++++++++++ public/js/ui.js | 37 +++++++++++++++++++++++++++++++++---- server.js | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/public/js/sse.js b/public/js/sse.js index e6416cb..0943c7f 100644 --- a/public/js/sse.js +++ b/public/js/sse.js @@ -84,6 +84,17 @@ function startSSE() { refreshDetailIfOpen(tid); }); + sseSource.addEventListener('intra_addfield',e=>{ + const d=JSON.parse(e.data); + const item=allData.find((x)=>String(x.task.id)===String(d.task_id)); + if(item) item.task._addfield_status=d.value||null; + if(d.by!==currentUser?.username){ + showToast(`πŸ”— ${d.by}: слуТ. статус β†’ Β«${d.value||'β€”'}Β» #${taskNumFromId(d.task_id)}`,'info'); + } + renderTable(); + refreshDetailIfOpen(d.task_id); + }); + sseSource.addEventListener('tasks_updated',e=>{ const d=JSON.parse(e.data); const incomingVersion=Number(d.cache_version||0); diff --git a/public/js/ui.js b/public/js/ui.js index 2ce4c4b..f98dfcc 100644 --- a/public/js/ui.js +++ b/public/js/ui.js @@ -455,9 +455,8 @@ function intraStatusBadge(task) { else if (lc.includes('ΠΎΠΆΠΈΠ΄Π°Π½') || lc.includes('hold')) cls = 'sb-intra-hold'; return `${esc(name)}`; } -// ── IntraDesk additional field status badge ─────────────────────── -function intraAddfieldBadge(task) { - const val = task._addfield_status; +// ── IntraDesk additional field β€” badge helper ───────────────────── +function _addfieldBadgeHtml(val) { if (!val) return 'β€”'; const match = (typeof MARKS_CONFIG !== 'undefined' ? MARKS_CONFIG : []) .find((m) => m.label && m.label.toLowerCase() === val.toLowerCase()); @@ -467,6 +466,36 @@ function intraAddfieldBadge(task) { } return `${esc(val)}`; } + +// ── IntraDesk additional field β€” interactive picker ─────────────── +function intraAddfieldPickerHtml(task) { + const tid = String(task.id); + const val = task._addfield_status || null; + const cfg = typeof MARKS_CONFIG !== 'undefined' ? MARKS_CONFIG : []; + const items = cfg.map((m) => ` +
+ ${esc(m.label)} +
`).join(''); + const clearItem = `
+ β€” ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ +
`; + return `
+ ${_addfieldBadgeHtml(val)} +
+
${items}${clearItem}
+
+
`; +} + +async function setIntraAddfield(taskId, value, e) { + if (e) e.stopPropagation(); + const r = await apiPost(`/api/tasks/${taskId}/intra-addfield`, { value: value || null }); + if (!r?.ok) { showToast(`❌ ${r?.error || 'Ошибка'}`, 'warn'); return; } + // ОбновляСм кСш локально Π΄ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ SSE + const item = allData.find((d) => String(d.task.id) === String(taskId)); + if (item) { item.task._addfield_status = value || null; renderTable(); } +} // Who answered β€” ring class for avatar function whoAnsweredRing(lc){ if(!lc) return 'ring-none'; @@ -756,7 +785,7 @@ function renderTable(keepPage){ ${sc('num') ?`#${num}${unreadDot}`:''} ${sc('title') ?`
${esc(task.name)}
${orgName?`
${esc(orgName)}
`:''}`:''} ${sc('intrastatus')?`${intraStatusBadge(task)}`:''} - ${sc('servstatus') ?`${intraAddfieldBadge(task)}`:''} + ${sc('servstatus') ?`${intraAddfieldPickerHtml(task)}`:''} ${sc('status') ?`${statusPickerHtml(tid)}`:''} ${sc('client') ?`
${avatarInitials(authorName)}
diff --git a/server.js b/server.js index 37cc83c..1249f49 100644 --- a/server.js +++ b/server.js @@ -790,6 +790,38 @@ app.post('/api/marks', auth, (req, res) => { res.json({ ok: true }); }); +// ── IntraDesk additional field (direct set) ─────────────────────── +app.post('/api/tasks/:taskId/intra-addfield', auth, async (req, res) => { + const taskId = String(req.params.taskId || '').trim(); + const { value } = req.body || {}; + const statusLabel = value ? String(value).trim() : null; + if (!taskId) return res.status(400).json({ error: 'task_id required' }); + + const s = getSettings(); + if (!s.api_key) return res.status(400).json({ error: 'API ΠΊΠ»ΡŽΡ‡ Π½Π΅ Π·Π°Π΄Π°Π½' }); + + const cacheRow = db.prepare('SELECT data FROM tasks_cache WHERE id=1').get(); + const tasks = JSON.parse(cacheRow?.data || '[]'); + const task = tasks.find((t) => String(t.id) === taskId); + if (!task) return res.status(404).json({ error: 'Π—Π°Π΄Π°Ρ‡Π° Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° Π² кСшС' }); + + try { + await refreshService.updateIntraAdditionalField(task.tasknumber, statusLabel, s.api_key); + } catch (e) { + console.error('[AddField] IntraDesk update error:', e.message); + return res.status(502).json({ error: `Ошибка IntraDesk: ${e.message}` }); + } + + // ОбновляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² локальном кСшС Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ + task._addfield_status = statusLabel; + const now = new Date().toISOString(); + db.prepare('UPDATE tasks_cache SET data=?, updated_at=? WHERE id=1') + .run(JSON.stringify(tasks), now); + + sseBroadcast('intra_addfield', { task_id: taskId, value: statusLabel, by: req.user.username }); + res.json({ ok: true, value: statusLabel }); +}); + // ── Notes ───────────────────────────────────────────────────────── app.get('/api/notes', auth, (req, res) => { const r = {};