Super Productivity 标签视图(Tag View)完全指南:跨项目分类、筛选与虚拟标签机制
2026/9/13 14:00:12 网站建设 项目流程

Super Productivity 标签视图(Tag View)完全指南:跨项目分类、筛选与虚拟标签机制

【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity

标签(Tag)是 Super Productivity 中用于跨项目灵活分类的核心轻量级机制:每个任务必须归属于恰好一个项目(Project),但可以携带零个、一个或多个标签。本篇指南以官方 wiki 的 Tag View 文档为骨架,结合仓库源码(src/app/features/tag/src/app/features/tasks/)深入讲解标签的定位、创建方式、筛选逻辑,以及 “Today” 虚拟标签的底层实现,读完后你将掌握完整的标签使用与扩展能力。

标签解决什么问题:项目的结构性 vs 标签的横切性

Super Productivity 中每个任务都必须且只能属于一个项目(Project),项目提供的是结构性组织(backlog、备注、主题、集成等一整套工作上下文)。这种强约束保证了任务归属清晰,但无法表达跨项目的共同属性——比如一个任务属于 "Backend API" 项目,同时又带有#urgent#bug#needs-review这类横切属性。

标签正是为此设计的:它允许你在不改变项目结构的前提下,从多个维度对任务打标,实现:

  • 多维分类:用项目做结构组织(每个任务恰好一个),用标签做横切组织(每个任务零到多个);
  • 灵活筛选:跨项目查看所有 "urgent" 任务、所有 "bug" 任务,而不必关心它们各自属于哪个项目;
  • 轻量管理:标签就是简单的标签——没有 backlog、备注、主题等复杂配置,创建和使用成本极低。

标签 vs 项目对比

维度标签(Tags)项目(Projects)
与任务的关系每个任务零个或多个(可选)每个任务恰好一个(必填)
用途跨项目灵活分类的横切标签主要的结构性组织单元
功能特性简单的筛选与分组标签Backlog、备注、主题、集成等完整工作上下文

在数据模型上,这种区别体现在源码中:标签实体Tag继承自WorkContextCommon(与项目共享工作上下文公共字段),并通过Task.tagIds: string[]与任务建立多对多关联,而项目通过Task.projectId与任务建立一对多关联。相关模型定义见 tag.model.ts。

多标签:为一个任务打上多个标签

任务可以携带多个标签,主要途径有三种:

  1. 任务标题短语法(Short Syntax):在标题中直接输入#tagname,例如"Fix login bug #urgent #bug #backend"
  2. 添加任务栏(Add Task Bar):通过复选框一次勾选多个标签;
  3. 标签编辑对话框:在编辑任务时添加或移除多个标签。

这样你就能按紧迫度、类型、领域或任何适合自己工作流的维度对任务进行多维分类。

底层实现:短语法标签解析

短语法#tagname的解析实现在 short-syntax.ts 中。其核心正则如下:

const CH_TAG = '#'; const ALL_SPECIAL = `(\\${CH_PRO}|\\${CH_TAG}|\\${CH_DUE}|\\${CH_DEADLINE})`; const SHORT_SYNTAX_TAGS_REG_EX = new RegExp(`\\${CH_TAG}[^${ALL_SPECIAL}|\\s]+`, 'gi');

也就是说:#后跟任意非空白、非特殊符号(+#@!|)的连续字符会被识别为一个标签 token。解析器parseTagChanges随后会:

  • 大小写不敏感匹配:将输入标签与现有标签做newTagTitle.toLowerCase() === tag.title.toLowerCase()匹配,命中则复用已有标签 ID;
  • 自动创建新标签:未匹配到的标签名进入newTagTitlesToCreate列表,由后续逻辑自动创建;
  • 从标题中剥离:被识别的标签 token 会从任务标题中移除,确保最终标题干净,只保留语义文本。

一个值得注意的细节是Fun title#blu不会被当作标签——解析器会检查#前一个字符,若它不是空格则拒绝解析,避免把普通文本误识别为标签。此外,纯数字标签(如#123)在标题开头以及 issue 任务上会被屏蔽,相关规则见parseTagChanges中的isNumericOnly判断。

在添加任务栏中与语法联动

添加任务栏的实时解析由 add-task-bar-parser.service.ts 完成。当你输入#tag时,解析器会维护tagIdsnewTagTitles两个状态,并在你通过控件勾选标签时,通过removeShortSyntaxFromInput('tags', specificTag)精确移除输入文本中对应的#tag片段——这里采用解析器记录的 token 范围(_lastParsedRanges)而非简单的正则替换,避免多词 token 被截断。

按标签筛选:跨项目查看任务

你可以按标签筛选任务,查看所有项目中带有特定标签的任务。筛选能力包括:

  • 标签名搜索:输入标签名的部分内容即可匹配(大小写不敏感);
  • 无标签筛选:筛出所有未打任何标签的任务。

查看某个标签时,你会看到来自多个项目的任务,每个任务以项目徽章(badge)形式展示其所属项目,便于一眼确认来源。

底层实现:标签成员关系的单一事实源

从源码看,标签与任务的关系采用“hybrid pattern”设计(见 tag.reducer.ts 中的computeOrderedTaskIdsForTag):

  • 成员关系:以task.tagIds单一事实源(single source of truth),只要任务的tagIds包含该标签 ID,任务就属于该标签;
  • 排序保持tag.taskIds仅用于保存用户自定义的排序,不参与成员判定;
  • 自愈能力tag.taskIds中的过期任务 ID 会被自动过滤,而带标签但未出现在排序列表中的任务会被自动追加到末尾。

这种设计让成员关系始终正确,同时保留用户拖拽排序的能力。筛选“无标签任务”正是基于task.tagIds为空数组这一事实实现的。

特殊场景:Today 虚拟标签

"Today"(今日)视图使用一种特殊的虚拟标签(virtual tag)模式。其成员关系不是从任务的标签列表中读取 "Today" 值,而是由任务的到期日(due day)或到期时间(due time)结合配置的逻辑日边界(logical-day boundary)实时计算得出。

这种设计的意义在于:Today 视图专注于基于时间的组织,而标签保持基于分类的组织,两者职责分离、互不干扰。Today 视图的详细工作方式见 4.01-The-Today-View。

底层实现:TODAY_TAG 的虚拟性

TODAY_TAG的定义与设计约束见 tag.const.ts,其注释明确列出了三条规则:

  1. 不应出现在task.tagIds——成员关系由task.dueDay决定;
  2. TODAY_TAG.taskIds仅存储今日任务的排序
  3. 移动操作(拖拽、Ctrl+↑/↓)通过tag.reducer.ts对包括 TODAY 在内的所有标签统一生效。
export const TODAY_TAG: Tag = { color: null, created: Date.now(), ...WORK_CONTEXT_DEFAULT_COMMON, icon: 'wb_sunny', title: 'Today', id: 'TODAY', theme: { ...WORK_CONTEXT_DEFAULT_THEME, isAutoContrast: true, huePrimary: '400', hueAccent: '500', hueWarn: '500', primary: DEFAULT_TODAY_TAG_COLOR, isDisableBackgroundTint: true, }, };

对应地,reducer 顶部同样以注释强调:“TODAY_TAG (ID: 'TODAY') 是虚拟标签,绝不应出现在 task.tagIds 中,成员关系由 task.dueDay 决定”。同时tag.reducer.ts中保留了selectTodayTagTaskIds选择器(标注@deprecated),并建议改用work-context.selectors.ts中的selectTodayTaskIds——后者直接从task.dueDay计算成员关系,具备自愈能力。这正印证了文档中“成员由到期日计算、而非标签列表”的描述。

标签的扩展用法

wiki 提供了两套基于标签的成熟工作流:

  • 4.07a-Tags_Eat-the-Frog —— 基于优先级的 A/B/C/D 打标法(吃青蛙法);
  • 4.07b-Tags_Ordinal-Priorities —— 用标签近似表达优先级顺序。

这两篇文章都依赖本文的“多标签 + 标签筛选”能力来实现:先创建代表优先级的标签(如#a#b),再通过给任务打标并在 Tag View 中筛选,即可获得跨项目的优先级视图。

标签的高级数据特性

除了文档中的基础能力,仓库源码还揭示了标签模型更丰富的维度(tag.model.ts、tag.service.ts):

  • 主题与颜色:每个标签都可以配置主题(theme.primaryhuePrimaryhueAccent等)或直接指定color,并通过TagComponent(见 tag/tag.component.ts)渲染为带颜色的徽章,同时支持 emoji 图标(isSingleEmoji判断);
  • 系统标签排除SYSTEM_TAG_IDSTODAYEM_URGENTEM_IMPORTANTKANBAN_IN_PROGRESS)用于在统计用户自建标签时排除系统自动创建的标签;
  • 按标签统计时间:tasks-by-tag.component.ts 会汇总每个标签下任务当日(或含昨日)的timeSpentOnDay,并按耗时降序排列,让你直观看到每个标签消耗了多少时间;
  • 排序管理:通过updateOrder/updateTagOrderaction 持久化标签在菜单中的树形排序(buildTagListInTreeOrder)。

相关阅读

  • 4.06-Project-View —— 项目如何提供结构性组织(必填)vs 标签(可选);
  • 4.05-Board-View —— 看板视图,可基于标签进行筛选与列组织;
  • 4.01-The-Today-View —— 基于时间的 Today 视图(使用虚拟标签模式);
  • 3.04-Short-Syntax —— 完整的短语法参考,包括#tagname标签语法及其他 token。

【免费下载链接】super-productivitySuper Productivity is an advanced todo list app with integrated Timeboxing and time tracking capabilities. It also comes with integrations for Jira, GitLab, GitHub and Open Project.项目地址: https://gitcode.com/GitHub_Trending/su/super-productivity

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询