任务面板:加保存按钮,负责人和分类改为可编辑 (#76)
用户 2026-11-05:「时间控件是对的,但是现在没有保存按钮,只有下面一个
评论的发表按钮。另外,负责人和分类都没法修改,按道理讲都应该可以修改才对。」
三处改动:
① 取消"立即保存",改成显式「保存」按钮
上一版(#74)做的是"选完截止时间就发请求"。用户不认可:他要的是
"改完点一下保存"那种确定感。
⇒ 移除 bindDue() 的 change 监听,改成 save-attrs 动作一次性提交三项。
② 负责人 / 分类 从只读改成可编辑
改前是只读 dl.kv 行,而且**值为空时整行不渲染**
(if (!empty($tpT[assignee_name])) / if ($tpCatName !== ))
⇒ 用户不仅改不了,连"这一项存在"都看不出来。
现在三项合成「更多信息」小节:
截止 [ AntD 日期控件 ]
负责人 [ 下拉 ]
分类 [ 下拉 ]
[ 保存 ]
负责人用原生 select 而不是 _person_picker.php 的弹窗选人:
面板已在浮层里,再弹一层模态 = 两层遮罩,手机上容易点错;
且 picker 需要 fbInitPickers() 初始化,loadPanel() 目前没调它。
家里 3~10 人 select 够用;人多了再换,那时记得把 fbInitPickers
也补进 loadPanel()。
③ Task::setAttrs()(新增)
只更新 due_at / assignee_id / category_id 三列。
不复用 update():那是全字段覆盖,面板只交三项的话
title/note/status/repeat/parent/board 会被默认值抹空
—— 与 setDue() 记的是同一个坑。
用 array_key_exists 判"传没传",这样可以只改其中一项
(面板在"没有成员"等极端情况下可能不渲染负责人下拉,
那时不该把它当成 0 去清掉原值)。
路由 tasks/panel_save:只把表单**真的提交了**的字段放进 $sd,
与 status/move 同一套约定(ajax_panel=1 回整块新面板)。
清理:bindDue / window.fbTaskPanelBindDue 全部移除
(entry_popup.js 里的调用、task_panel.js 里的定义与导出)
—— 留着会引用未定义函数,直接抛错。
实测:
三项一起改 => due_at/assignee/category 全对 ✅
标题/状态/备注/看板 均未被破坏 ✅
只改 due_at => 另两项保留、未被清空 ✅
面板渲染 => save-url / 保存按钮 / 两个下拉 / AntD 控件 /
原有状态/附件/评论 全部在位 ✅
This commit is contained in:
@@ -749,6 +749,56 @@ final class Task
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只更新「截止时间 / 负责人 / 分类」三项(#76)。
|
||||
*
|
||||
* 🔴 用户 2026-11-05:「负责人和分类都没法修改,按道理讲都应该可以修改才对。」
|
||||
* 上一版面板里这三项都是只读的 `dl.kv` 行。
|
||||
*
|
||||
* ⚠️ **不要复用 `update()`**:那是全字段覆盖。面板只交这三项的话,
|
||||
* title / note / status / repeat / parent / board 会被默认值抹空 ——
|
||||
* 与 `setDue()` 记的是同一个坑。
|
||||
*
|
||||
* ⚠️ 三个参数都「显式传」才算改:`due_at` 传 `null` = 不动;
|
||||
* 传 `''` = 清掉。这样调用方可以只改其中一项。
|
||||
* (用 `array_key_exists` 判"传没传",而不是 `isset` ——
|
||||
* `isset(null)` 为 false,会把"显式传 null"误判成"没传"。)
|
||||
*
|
||||
* @param array $d 可含 due_at / assignee_id / category_id
|
||||
*/
|
||||
public static function setAttrs(int $familyId, int $id, array $d): bool
|
||||
{
|
||||
$old = self::row($familyId, $id);
|
||||
if (!$old) {
|
||||
return false;
|
||||
}
|
||||
$sets = [];
|
||||
$args = [];
|
||||
if (array_key_exists('due_at', $d)) {
|
||||
$sets[] = 'due_at = ?';
|
||||
$args[] = self::dtOrNull((string)($d['due_at'] ?? ''));
|
||||
}
|
||||
if (array_key_exists('assignee_id', $d)) {
|
||||
/* 0 / 空 = 不指定(存 NULL,与 update() 里 `?: null` 同一口径) */
|
||||
$sets[] = 'assignee_id = ?';
|
||||
$aid = (int)($d['assignee_id'] ?? 0);
|
||||
$args[] = $aid > 0 ? $aid : null;
|
||||
}
|
||||
if (array_key_exists('category_id', $d)) {
|
||||
$sets[] = 'category_id = ?';
|
||||
$args[] = self::categoryIdOf($familyId, (int)($d['category_id'] ?? 0));
|
||||
}
|
||||
if (!$sets) {
|
||||
return true; // 三个都没传:什么都不做,但也算"成功"(幂等)
|
||||
}
|
||||
$args[] = $id;
|
||||
$args[] = $familyId;
|
||||
Database::get()->prepare(
|
||||
'UPDATE tasks SET ' . implode(', ', $sets) . ' WHERE id = ? AND family_id = ?'
|
||||
)->execute($args);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function setStatus(int $familyId, int $id, string $status, int $position = 0): int
|
||||
{
|
||||
$old = self::row($familyId, $id);
|
||||
|
||||
Reference in New Issue
Block a user