鸿蒙端:分类、循环改成可编辑 (#83)
用户 2026-11-05:「分类和重复,也就是循环,都需要加上,鸿蒙端也得加上。」 原来这两个只在**有值**时才画一行只读文字 (`if (this.categoryOf() !== )` / `if (this.repeatOf() !== )`)—— 用户不仅改不了,连"这里本来有这一项"都看不出来。 (这与 #76 里网页端"负责人为空就整行消失"是同一个毛病。) 改法:与截止/负责人同形态(标签一行 + 控件一行),**始终显示**。 ① FbTaskPanel 新增 `@Param cats: FbCatOpt[]` ⚠️ 与 boards 同一理由:**不能从任务里反推** —— 反推只能看见"已经被用过的"分类,新建的分类在端上永远选不到。 ② 下拉用 ArkUI 原生 `Select`,第 0 项固定「未分类」/「不循环」 - 分类:index 0 → category_id = 0;index N → cats[N-1].id - 循环:index 0 → (不循环);index N → REPEAT_KEYS[N-1] ⚠️ REPEAT_KEYS 与 REPEAT_WORDS **必须严格对齐**, 错一位就是"选每天存成每周"这种静默错数据。 ③ `inlineBusy` 时退回只读文字:请求在飞的时候不给选, 否则用户连点两下会发两次相反的值。 ④ 首页 / 任务页两处宿主传 `cats`(tskCats / metaCats)。 ⑤ 服务端 API 早就支持这两个字段(`Api::str(repeat_rule, ...)`), 本轮只补了 `Task::setAttrs` 的 repeat_rule 分支(见服务端那次提交)。 编译通过,已装真机。
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
import { FbColors, FbMetric, FB_MASK, fbAlpha, fbTint } from '../common/Theme';
|
||||
import {
|
||||
FbBoardOpt, FbTaskAttach, FbTaskComment, FbTaskDetail, FbTaskItem, FbTaskKid, FbTaskShare,
|
||||
FbBoardOpt, FbCatOpt, FbTaskAttach, FbTaskComment, FbTaskDetail, FbTaskItem, FbTaskKid, FbTaskShare,
|
||||
} from '../model/Types';
|
||||
import { FbSheetRing } from './FbSheetRing';
|
||||
import { FbSheetClose } from './FbSheetClose';
|
||||
@@ -69,6 +69,16 @@ export struct FbTaskPanel {
|
||||
@Param seed: FbTaskItem | null = null;
|
||||
/** 全部看板(含空看板)—— 父页面用 `?view=boards` 拿,别从任务里反推 */
|
||||
@Param boards: FbBoardOpt[] = [];
|
||||
/**
|
||||
* 全部分类(`id=0` 由这里补「未分类」,所以传进来的是"真实分类")。
|
||||
*
|
||||
* 🔴 #83(用户 2026-11-05):「分类和重复,也就是循环,都需要加上,
|
||||
* 鸿蒙端也得加上。」
|
||||
*
|
||||
* ⚠️ 与 boards 同一理由:**不能从任务里反推** ——
|
||||
* 反推只能看见"已经被用过的"分类,新建的分类在端上永远选不到。
|
||||
*/
|
||||
@Param cats: FbCatOpt[] = [];
|
||||
/** 模块主题色(任务 = 赭红) */
|
||||
@Param accent: string = '#A8574F';
|
||||
/**
|
||||
@@ -1445,13 +1455,77 @@ export struct FbTaskPanel {
|
||||
.width('100%')
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
/* ---- 分类 / 循环(同样上下两行)---- */
|
||||
if (this.categoryOf() !== '') {
|
||||
this.kvRow('分类', this.categoryOf())
|
||||
/* ---- 分类 ---- */
|
||||
/* 🔴 #83(用户 2026-11-05):「分类和重复,也就是循环,都需要加上。」
|
||||
原来这两个只在**有值**时才画一行只读文字 ——
|
||||
用户不仅改不了,连"这里本来有这一项"都看不出来。
|
||||
⇒ 改成与截止/负责人同形态(标签一行 + 控件一行),且始终显示。 */
|
||||
Column({ space: 6 }) {
|
||||
this.fieldLb('分类')
|
||||
if (this.inlineBusy) {
|
||||
Text(this.categoryOf() !== '' ? this.categoryOf() : '未分类')
|
||||
.fontSize(FbMetric.fontSmall)
|
||||
.fontColor(FbColors.faint)
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.padding({ left: 12, right: 12 })
|
||||
.backgroundColor(FbColors.inputBg)
|
||||
.borderRadius(FbMetric.radiusS)
|
||||
} else {
|
||||
Select(this.catOptions())
|
||||
.selected(this.catIndex())
|
||||
.value(this.categoryOf() !== '' ? this.categoryOf() : '未分类')
|
||||
.font({ size: FbMetric.fontSmall })
|
||||
.fontColor(FbColors.ink)
|
||||
.selectedOptionFont({ size: FbMetric.fontSmall })
|
||||
.optionFont({ size: FbMetric.fontSmall })
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.backgroundColor(FbColors.inputBg)
|
||||
.borderRadius(FbMetric.radiusS)
|
||||
.onSelect((idx: number): void => {
|
||||
/* index 0 = 「未分类」→ category_id 传 0 */
|
||||
const cid: number = idx === 0 ? 0
|
||||
: (idx - 1 < this.cats.length ? this.cats[idx - 1].id : 0);
|
||||
this.saveField('category_id', '', cid);
|
||||
})
|
||||
}
|
||||
if (this.repeatOf() !== '') {
|
||||
this.kvRow('循环', this.repeatOf())
|
||||
}
|
||||
.width('100%')
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
/* ---- 循环 ---- */
|
||||
Column({ space: 6 }) {
|
||||
this.fieldLb('循环')
|
||||
if (this.inlineBusy) {
|
||||
Text(this.repeatOf() !== '' ? this.repeatOf() : '不循环')
|
||||
.fontSize(FbMetric.fontSmall)
|
||||
.fontColor(FbColors.faint)
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.padding({ left: 12, right: 12 })
|
||||
.backgroundColor(FbColors.inputBg)
|
||||
.borderRadius(FbMetric.radiusS)
|
||||
} else {
|
||||
Select(this.repeatOptions())
|
||||
.selected(this.repeatIndex())
|
||||
.value(this.repeatOf() !== '' ? this.repeatWordOf(this.repeatOf()) : '不循环')
|
||||
.font({ size: FbMetric.fontSmall })
|
||||
.fontColor(FbColors.ink)
|
||||
.selectedOptionFont({ size: FbMetric.fontSmall })
|
||||
.optionFont({ size: FbMetric.fontSmall })
|
||||
.width('100%')
|
||||
.height(40)
|
||||
.backgroundColor(FbColors.inputBg)
|
||||
.borderRadius(FbMetric.radiusS)
|
||||
.onSelect((idx: number): void => {
|
||||
const rk: string = idx === 0 ? '' : FbTaskPanel.REPEAT_KEYS[idx - 1];
|
||||
this.saveField('repeat_rule', rk, -1);
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
|
||||
/* ---- 备注 ---- */
|
||||
/* 🔴 #77n(用户 2026-11-05):「包括下面的备注也是一样」
|
||||
@@ -1488,6 +1562,66 @@ export struct FbTaskPanel {
|
||||
.padding({ top: 4 })
|
||||
}
|
||||
|
||||
/* ---------------- 分类 / 循环 的下拉选项 ---------------- */
|
||||
|
||||
/**
|
||||
* 循环的可选键(与编辑表单 `FbTaskEditSheet.repeatChip` 同一套)。
|
||||
* ⚠️ 顺序必须与 `REPEAT_WORDS` 严格对齐 —— 两边错一位就会"选每天存成每周"。
|
||||
*/
|
||||
private static readonly REPEAT_KEYS: string[] = ['day', 'week', 'month', 'year'];
|
||||
private static readonly REPEAT_WORDS: string[] = ['每天', '每周', '每月', '每年'];
|
||||
|
||||
/** 分类下拉的选项文本:第 0 项固定是「未分类」(对应 category_id = 0) */
|
||||
private catOptions(): SelectOption[] {
|
||||
const out: SelectOption[] = [{ value: '未分类' }];
|
||||
for (let i = 0; i < this.cats.length; i++) {
|
||||
out.push({ value: this.cats[i].name });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** 当前选中的下标(0 = 未分类) */
|
||||
private catIndex(): number {
|
||||
const d: FbTaskDetail | null = this.detail;
|
||||
const cid: number = d !== null ? d.categoryId : 0;
|
||||
if (cid <= 0) {
|
||||
return 0;
|
||||
}
|
||||
for (let i = 0; i < this.cats.length; i++) {
|
||||
if (this.cats[i].id === cid) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 0; // 分类被删了/不在这份清单里 → 显示未分类
|
||||
}
|
||||
|
||||
private repeatOptions(): SelectOption[] {
|
||||
const out: SelectOption[] = [{ value: '不循环' }];
|
||||
for (let i = 0; i < FbTaskPanel.REPEAT_WORDS.length; i++) {
|
||||
out.push({ value: FbTaskPanel.REPEAT_WORDS[i] });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private repeatIndex(): number {
|
||||
const r: string = this.repeatOf();
|
||||
for (let i = 0; i < FbTaskPanel.REPEAT_KEYS.length; i++) {
|
||||
if (FbTaskPanel.REPEAT_KEYS[i] === r) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private repeatWordOf(key: string): string {
|
||||
for (let i = 0; i < FbTaskPanel.REPEAT_KEYS.length; i++) {
|
||||
if (FbTaskPanel.REPEAT_KEYS[i] === key) {
|
||||
return FbTaskPanel.REPEAT_WORDS[i];
|
||||
}
|
||||
}
|
||||
return '不循环';
|
||||
}
|
||||
|
||||
/** 截止时间的时分(`HH:mm`),给日期浮层做初值;没有期限就给当前时刻 */
|
||||
private dueTimeOf(): string {
|
||||
const t: FbTaskItem | null = this.cur();
|
||||
|
||||
@@ -1950,6 +1950,7 @@ export struct FbHomePage {
|
||||
taskId: this.tskBase.id,
|
||||
seed: this.tskBase,
|
||||
boards: this.tskBoards,
|
||||
cats: this.tskCats,
|
||||
accent: this.taskAccent(),
|
||||
refreshTick: this.tskTick,
|
||||
onClose: (): void => {
|
||||
|
||||
@@ -547,6 +547,7 @@ export struct FbTasksPage {
|
||||
taskId: this.panelId,
|
||||
seed: this.panelSeed,
|
||||
boards: this.boardOpts(),
|
||||
cats: this.metaCats,
|
||||
accent: this.accent,
|
||||
refreshTick: this.panelTick,
|
||||
onClose: (): void => {
|
||||
|
||||
Reference in New Issue
Block a user