用户原话: 「网页端,首页点击一个任务后,除了展示信息,应该有相应的功能,可以修改状态: 待办、进行中,可以挪动分组,可以拖动上传附件,可以添加评论,添加子任务等。 其目地,是为了让用户不离开首页,就能对任务进行简单的处理。」 「另外,在全部任务旁边,放一个新建任务的功能,其实就是把任务中的新建和编辑功能, 搬过来,用弹出框来处理。」 一、首页任务浮层由「只读信息」改成「可操作面板」 - 新增 templates/tasks/_panel.php:状态三段 / 看板 chips(带看板色)/ 子任务(复用 _task_check.php)/ 附件拖放框(复用 _attachments.php)/ 讨论 - 新增路由 tasks/panel:只吐一块 HTML(找不到 404) - 既有七个动作路由各加一条 ajax_panel 回包分支(状态 / 挪分组 / 新建子任务 / 评论增删 / 附件增删),没有新开写接口 - helpers.php 新增 task_panel_wanted() / task_panel_json(); fb_entry_json() 的 payload 增加 panel 字段(只有任务会给) - 每次动作回**整块新面板**:一次动作会牵动子任务计数、附件张数、看板选中态, 逐处同步 DOM 必然漏一处 - 拖进来的附件**立刻上传**(任务已存在,不该再让用户点一次保存), 不复用 _stage_drop.php 那套「暂存 + 认领」 二、新建任务搬到首页 - 从 templates/tasks/index.php 抽出公共片段 templates/tasks/_add_modal.php (字段与原来一字未改),首页与任务页共用同一份 - 新增 assets/js/task_add.js 管开关(两页共用,幂等绑定); 打开那一刻才 fbUpgradeRange() + fbBootAntd()(hidden 时宽高为 0,antd 会定位错乱) - App\HomeCards 登记表里加 add => 新建任务,首页卡头与「全部任务」并排 - tasks/create 支持 back=home(白名单),新建完回首页 三、其它 - assets/js/task_panel.js:事件委托;动作后整块换面板; 顺手同步首页那张卡的状态徽标与复选框(关掉浮层不能还是旧状态); 传附件时保住用户写了一半的留言与子任务标题;取不到面板时退回只读信息 - app.css 追加面板样式(含 color-mix 的 @supports 兜底)与卡片窄到宽 2 时允许折行 验证:本地 e2e 1558/0、几何 428/0 + 660/0、v78 反向验证 11/0、 片段作用域体检 35/0、php -l 与 node --check 全过
63 lines
2.9 KiB
JavaScript
63 lines
2.9 KiB
JavaScript
/* ============================================================================
|
||
「新建任务」弹框的开关(v78)
|
||
----------------------------------------------------------------------------
|
||
用户原话(2026-10-22):「在全部任务旁边,放一个新建任务的功能,其实就是把任务中的
|
||
新建和编辑功能,搬过来,用弹出框来处理。」
|
||
|
||
两个入口、一张弹框:
|
||
· 任务看板页(`tasks/index.php`)页头那颗「新建任务」;
|
||
· 首页「近期任务」卡片右上角那颗(在「全部任务」右边)。
|
||
两处都是 `data-tk-add-open`,弹框本体是 `templates/tasks/_add_modal.php`。
|
||
|
||
为什么单独成一个脚本(而不是各页写一段内联):
|
||
· 内联脚本在 AJAX 换正文时**不会被重跑**(v42/v47 连着栽过两次);
|
||
· 两个入口各写一段,必然有一处忘了在**打开那一刻**再 boot 一次日期控件 ——
|
||
而弹框初始是 `hidden`,antd 面板拿到 0 尺寸会定位到屏幕左上角
|
||
(`tasks/show.php` 的编辑弹框就是为这个专门 boot 过,这里照抄同一手法)。
|
||
|
||
⚠️ 全站加载,但有幂等闸门、页面里没有这张弹框时**什么都不做**(几行判断而已)。
|
||
============================================================================ */
|
||
(function () {
|
||
'use strict';
|
||
if (window.__fbTkAddBound) { return; }
|
||
window.__fbTkAddBound = true;
|
||
|
||
function card() { return document.getElementById('taskAddCard'); }
|
||
|
||
function setOpen(on) {
|
||
var c = card();
|
||
if (!c) { return; }
|
||
c.hidden = !on;
|
||
if (!on) { return; }
|
||
/* 打开这一刻才升级日期控件(hidden 时宽高为 0,antd 面板会定位错乱)。
|
||
两步都要:先绑自建下拉(兜底),再挂 antd(正主);两个函数都自判幂等。 */
|
||
if (window.fbUpgradeRange) { window.fbUpgradeRange(); }
|
||
if (window.fbBootAntd) { window.fbBootAntd(); }
|
||
var t = document.getElementById('tk-title');
|
||
if (t) { t.focus(); }
|
||
}
|
||
|
||
function antdOpen() {
|
||
var d = document.querySelector('.ant-picker-dropdown');
|
||
return !!(d && !d.classList.contains('ant-picker-dropdown-hidden'));
|
||
}
|
||
|
||
document.addEventListener('click', function (e) {
|
||
var t = e.target;
|
||
if (!t || !t.closest) { return; }
|
||
if (t.closest('[data-tk-add-open]')) { e.preventDefault(); setOpen(true); return; }
|
||
if (t.closest('[data-tk-add-close]')) { e.preventDefault(); setOpen(false); return; }
|
||
var c = card();
|
||
/* 点遮罩关、点面板内不关 —— 与站内其它浮层同一套行为 */
|
||
if (c && t === c) { setOpen(false); }
|
||
});
|
||
|
||
document.addEventListener('keydown', function (e) {
|
||
if (e.key !== 'Escape') { return; }
|
||
var c = card();
|
||
if (!c || c.hidden) { return; }
|
||
if (antdOpen()) { return; } // 让 antd 先收它自己的面板
|
||
setOpen(false);
|
||
});
|
||
})();
|