任务面板:去掉左上圆圈、标题下移成可编辑的「任务标题」(#77)

用户 2026-11-05:「还是不对,这个弹出框的标题是编辑任务,台式机采购这样的
东西,它是一个标题,也应该可以被修改才对。所以它应该往下放,就是任务标题;
然后台式机采购计划也往下放,也是可以修改的。左上角那个标志,好像一个圆圈
什么的,那个也不要了,去掉。」

① 删掉左上角的 FbCheckCircle("圆圈")
   它是"点一下勾完成"的快捷入口,但下面「状态」区已经有三个明确的 chip,
   入口重复。而且它紧贴标题左侧,视觉上像"标题前面的项目符号",
   反而让人以为标题前面该有个图标。

② 大标题从顶栏下移到「更多信息」区,成为第一项「任务标题」
   原来标题画在 headBar 里,所以它是**只读**的 —— 而标题本来就该能改。
   现在与截止/负责人/备注同形态:标题行 + 控件行,
   点一下变成 TextArea(height 64、字号 fontTitle 17、主题色),
   失焦自动保存(与备注同一套交互,不设保存按钮)。
   ⚠️ 空标题不发请求:服务端会清洗成空串,等于把标题删了。
   ⚠️ `saveField(title, ...)` 走的是既有 PATCH —— 服务端 ApiHandler
      对未提交字段回退原值,所以只传 title 不会把 note/due_at 抹掉。

③ headBar 只剩「状态徽标 + 关闭」,左端放「属于「父任务」」
   父任务那行保留在顶栏不跟着下移:它是上下文不是内容,
   跟标题走反而离"父任务"这个概念更远。
   没有父任务时用 Blank() 占位,保证徽标和关闭仍在右边。

④ 完成态标题仍是 faint + 删除线(不上主题色)
   删除线是"这件事已经过去了"的信号,再上主题色会和待办标题一样抢眼。

编译通过,已装真机。
This commit is contained in:
2026-11-05 19:41:14 +08:00
parent 2fefacccd3
commit 28c6e674ba
+104 -41
View File
@@ -121,6 +121,10 @@ export struct FbTaskPanel {
交互(那几处都是点一下就生效)。这里多一颗按钮反而不一致。 */ 交互(那几处都是点一下就生效)。这里多一颗按钮反而不一致。 */
@Local duePickOpen: boolean = false; @Local duePickOpen: boolean = false;
@Local attPickOpen: boolean = false; @Local attPickOpen: boolean = false;
/* #77l:「任务标题」也做成可编辑(用户 2026-11-05:
「台式机采购计划也往下放,也是可以修改的」) */
@Local titleEdit: boolean = false;
@Local titleDraft: string = '';
@Local noteEdit: boolean = false; @Local noteEdit: boolean = false;
@Local noteDraft: string = ''; @Local noteDraft: string = '';
@Local inlineBusy: boolean = false; @Local inlineBusy: boolean = false;
@@ -374,6 +378,19 @@ export struct FbTaskPanel {
} }
/** 保存备注(失焦/回车时触发) */ /** 保存备注(失焦/回车时触发) */
/** 保存任务标题(#77l) */
private async saveTitle(): Promise<void> {
if (!this.titleEdit) {
return;
}
this.titleEdit = false;
const v: string = this.titleDraft.trim();
if (v === '' || v === this.titleOf()) {
return; // 空标题不发请求(服务端也会清洗成空,等于把标题删了)
}
await this.saveField('title', v, -1);
}
private async saveNote(): Promise<void> { private async saveNote(): Promise<void> {
if (!this.noteEdit) { if (!this.noteEdit) {
return; return;
@@ -958,50 +975,39 @@ export struct FbTaskPanel {
.hitTestBehavior(HitTestMode.Transparent) .hitTestBehavior(HitTestMode.Transparent)
} }
/** 标题行:状态圈(点=勾完成)+ 标题 + 状态徽标 + 关闭 */ /**
* 顶栏:状态徽标 + 关闭。
*
* 🔴🔴 #77l(用户 2026-11-05):
* 「这个弹出框的标题是编辑任务,台式机采购这样的东西,它是一个标题,
* 也应该可以被修改才对。所以它应该往下放,就是任务标题;
* 然后台式机采购计划也往下放,也是可以修改的。
* 左上角那个标志,好像一个圆圈什么的,那个也不要了,去掉。」
*
* 三处变化:
* · **删掉左上角的 FbCheckCircle**(就是用户说的"圆圈")。它是"点一下勾完成"
* 的快捷入口,但下面「状态」区已经有三个明确的 chip,入口重复;
* 而且它紧贴标题,看起来像"标题前面的项目符号",容易误解。
* · **删掉这里的大标题**。原来标题画在这里,导致它是只读的 ——
* 标题本来就该能改,所以下移到「更多信息」区当第一个字段。
* · 只留状态徽标 + 关闭按钮,这一条变窄(原来 30+标题+徽标+关闭很挤)。
*
* ⚠️ 「属于「父任务」」那行**保留在这里**:它是上下文不是内容,
* 跟着标题下移反而会离"父任务"这个概念更远。
*/
@Builder @Builder
headBar() { headBar() {
Row({ space: 10 }) { Row({ space: 10 }) {
Stack({ alignContent: Alignment.Center }) { if (this.parentOf() !== '') {
FbCheckCircle({ Text('属于「' + this.parentOf() + '」')
dia: 18, .fontSize(FbMetric.fontTiny)
done: this.isDone(), .fontColor(FbColors.faint)
doing: this.statusOf() === 'doing', .maxLines(1)
color: this.accent .layoutWeight(1)
}) .flexShrink(1)
} else {
Blank()
} }
.width(30)
.height(30)
.onClick((): void => {
this.setStatus(this.isDone() ? 'todo' : 'done');
})
Column({ space: 2 }) {
/* 🔴 #77k(用户 2026-11-05):「上面"台式机采购计划"这样的标题,
应该是主题的颜色。」
⚠️ 完成态仍用 faint + 删除线:那条是"这件事已经过去了"的信号,
再上主题色会和"待办"的标题一样抢眼,反而分不出轻重。 */
Text(this.titleOf())
.fontSize(FbMetric.fontTitle)
.fontWeight(FontWeight.Bold)
.fontColor(this.isDone() ? FbColors.faint : this.accent)
.decoration({
type: this.isDone() ? TextDecorationType.LineThrough : TextDecorationType.None,
color: FbColors.faint
})
.maxLines(2)
.width('100%')
if (this.parentOf() !== '') {
Text('属于「' + this.parentOf() + '」')
.fontSize(FbMetric.fontTiny)
.fontColor(FbColors.faint)
.maxLines(1)
.width('100%')
}
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.flexShrink(1)
Text(this.statusWord(this.statusOf())) Text(this.statusWord(this.statusOf()))
.fontSize(FbMetric.fontTiny) .fontSize(FbMetric.fontTiny)
@@ -1018,7 +1024,7 @@ export struct FbTaskPanel {
}) })
} }
.width('100%') .width('100%')
.alignItems(VerticalAlign.Top) .alignItems(VerticalAlign.Center)
} }
/** 状态三段(点一下即改,没有"保存"按钮) */ /** 状态三段(点一下即改,没有"保存"按钮) */
@@ -1180,6 +1186,63 @@ export struct FbTaskPanel {
不给高度的话,「设置…」「未指定」这类短文字会把框压扁, 不给高度的话,「设置…」「未指定」这类短文字会把框压扁,
几行之间的间距就会参差不齐。 */ 几行之间的间距就会参差不齐。 */
Column({ space: 14 }) { Column({ space: 14 }) {
/* ---- 任务标题(可编辑,#77l 从顶栏下移到这里)---- */
Column({ space: 6 }) {
this.fieldLb('任务标题')
if (this.titleEdit) {
TextArea({ text: this.titleDraft, placeholder: '要做的事…' })
.placeholderColor(FbColors.faint)
.placeholderFont({ size: FbMetric.fontTiny })
.fontSize(FbMetric.fontTitle)
.fontColor(this.accent)
.backgroundColor(FbColors.inputBg)
.borderRadius(FbMetric.radiusS)
.width('100%')
.height(64)
.padding({ left: 12, right: 12, top: 10, bottom: 10 })
.onChange((v: string): void => {
this.titleDraft = v;
})
/* 失焦保存 —— 与备注同一套(用户改完直接点别处是最自然的动作,
让他再去找"保存"就会以为没存上)。 */
.onBlur((): void => {
this.saveTitle();
})
} else {
Row({ space: 8 }) {
Text(this.titleOf())
.fontSize(FbMetric.fontTitle)
.fontWeight(FontWeight.Bold)
.fontColor(this.isDone() ? FbColors.faint : this.accent)
.decoration({
type: this.isDone() ? TextDecorationType.LineThrough : TextDecorationType.None,
color: FbColors.faint
})
.maxLines(3)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.layoutWeight(1)
Text('✎')
.fontSize(FbMetric.fontTiny)
.fontColor(this.inlineBusy ? FbColors.faint : this.accent)
}
.width('100%')
.constraintSize({ minHeight: 44 })
.padding({ left: 12, right: 12, top: 11, bottom: 11 })
.backgroundColor(FbColors.inputBg)
.borderRadius(FbMetric.radiusS)
.alignItems(VerticalAlign.Top)
.onClick((): void => {
if (this.titleEdit || this.inlineBusy) {
return;
}
this.titleDraft = this.titleOf();
this.titleEdit = true;
})
}
}
.width('100%')
.alignItems(HorizontalAlign.Start)
/* ---- 截止 ---- */ /* ---- 截止 ---- */
Column({ space: 6 }) { Column({ space: 6 }) {
this.fieldLb('截止') this.fieldLb('截止')