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)}
+
+
`;
+}
+
+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') ?`
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 = {};
|