ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Homepage 接入 Vikunja:任务看板 Widget 配置与源码级原理解析

Homepage 接入 Vikunja:任务看板 Widget 配置与源码级原理解析 Homepage 接入 Vikunja任务看板 Widget 配置与源码级原理解析【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepageVikunja 是一款开源的任务管理与待办事项工具而 Homepage 为其提供了专用的服务 Widget让你能在统一的应用仪表盘中直接查看项目数量、本周到期任务、逾期任务与进行中任务。本文以 Homepage 仓库中的 Vikunja Widget 配置文档 为主体结合源码实现完整讲解配置参数、API 版本兼容策略、统计口径与任务列表的开启方式帮助你快速集成并理解其底层工作流程。Vikunja Widget 能做什么在 Homepage 的 services 布局中Vikunja Widget 通过调用 Vikunja 的 REST API 实时拉取数据并展示以下四类统计指标字段含义projects活跃项目Active Projects数量tasks7d本周到期任务Tasks Due This Week数量tasksOverdue逾期任务Overdue Tasks数量tasksInProgress进行中任务Tasks In Progress数量这四个字段也就是官方文档中声明的Allowed fields即 Widget 在卡片上可展示的全部指标块Block。此外文档还额外提供了一个enableTaskList选项默认关闭开启后会在卡片下方渲染按截止日期排序的最近 5 个任务列表。快速开始最小可用配置将以下 YAML 片段加入你的 services.yaml 对应服务条目中即可完成基本接入widget: type: vikunja url: http[s]://vikunja.host.or.ip[:port] key: vikunjaapikey enableTaskList: true # optional, defaults to false version: 2 # optional, defaults to 1其中url指向你的 Vikunja 服务地址支持 http/https 并可选端口key是你在 Vikunja 中生成的 API Key。其余两个参数为可选项含义详见下文。配置参数详解urlVikunja 实例的基础地址例如https://vikunja.example.com。Widget 发出的所有 API 请求都以此地址为前缀具体的端点拼接逻辑定义在 src/widgets/vikunja/widget.js 中api: {url}/api/v1/{endpoint},也就是说最终请求会被组合为{url}/api/v1/{endpoint}的形式其中{endpoint}由各数据映射mapping决定。keyVikunja API Key用于认证。在 src/utils/proxy/handlers/credentialed.js 中vikunja属于使用Bearer令牌认证的 widget 类型列表代理层会为请求附加如下请求头headers.Authorization Bearer ${widget.key};因此你需要在 Vikunja 中创建对应的 API Key具有读取任务和项目的权限并将其填入此处。注意该 Key 保存在配置文件中仅由 Homepage 后端代理使用不会暴露到浏览器端。versionAPI 版本兼容开关不同版本的 Vikunja 对所有任务接口的路径定义不同Homepage 通过version参数进行兼容取值与默认值如下Vikunja 版本Homepage Widget 版本 v1.0.0-rc41默认 v1.0.0-rc42从源码可以看到两个版本对应的任务端点并不相同mappings: { projects: { endpoint: projects, }, tasks: { endpoint: tasks/all?filterdone%3Dfalsesort_bydue_date, }, tasks_v2: { endpoint: tasks?filterdone%3Dfalsesort_bydue_date, }, },version: 1默认使用tasks/all端点version: 2使用tasks端点。两者都带上了 URL 编码后的查询参数filterdonefalsesort_bydue_date即只拉取未完成的任务并按截止日期排序——这正是后面任务列表和统计计算的数据基础。组件侧根据version选择调用哪一个映射见 src/widgets/vikunja/component.jsxconst version widget.version ?? 1; const { data: tasksData, error: tasksError } useWidgetAPI(widget, version 2 ? tasks_v2 : tasks);如果你使用的是新版本 Vikunja v1.0.0-rc4务必显式设置version: 2否则接口路径不匹配将导致数据拉取失败。enableTaskList任务列表开关enableTaskList默认值为false。当设置为true时组件会从排序后的任务数据中截取前 5 条逐条渲染任务标题与相对截止时间{widget.enableTaskList tasksData.slice(0, 5).map((task) ( ... ))}列表中的每项都会显示任务标题如果任务有真实的截止日期即非默认零值日期还会通过common.relativeDate本地化格式化展示相对时间如3 天后、昨天。没有截止日期的任务则只显示标题。四个统计指标的精确计算口径文档只声明了四个允许的字段但未说明它们的计算方式。通过 src/widgets/vikunja/component.jsx 的源码可以还原每个指标的确切口径projects活跃项目数const projects projectsData.filter((project) project.id 0); // saved filters have id 0Vikunja 的projects接口返回的列表中已保存的筛选器saved filters的 id 为负数因此组件只统计id 0的真实项目避免把筛选器误计入项目数。任务数据规范化任务数据在代理返回前会经过map函数清洗见 src/widgets/vikunja/widget.jsconst map (data) asJson(data).map((task) ({ id: task.id, title: task.title, priority: task.priority, dueDate: task.due_date, dueDateIsDefault: task.due_date 0001-01-01T00:00:00Z, inProgress: task.percent_done 0 task.percent_done 1, }));要点dueDateIsDefaultVikunja 用0001-01-01T00:00:00Z表示无截止日期该值会被识别出来避免被当作早已逾期inProgress当percent_done大于 0 且小于 1 时判定为进行中任务。tasks7d本周到期任务const oneWeekFromNow new Date(Date.now() 7 * 24 * 60 * 60 * 1000); const tasksWithDueDate tasksData.filter((task) !task.dueDateIsDefault); const tasks7d tasksWithDueDate.filter((task) new Date(task.dueDate) oneWeekFromNow);统计的是设置了真实截止日期、且截止时间在当前时间之后 7 天以内的未完成任务数。注意这里统计的是7 天窗口而非严格的自然周且已包含所有截止日期小于等于一周后的任务。tasksOverdue逾期任务const tasksOverdue tasksWithDueDate.filter((task) new Date(task.dueDate) new Date(Date.now()));统计截止日期早于或等于当前时刻的任务数。由于查询接口只返回未完成任务这里统计的是尚未完成但已过期的任务。tasksInProgress进行中任务const tasksInProgress tasksData.filter((task) task.inProgress);即percent_done处于(0, 1)开区间内的任务数量0% 与 100% 都不计入。加载与错误处理组件在数据加载完成前会渲染四个占位块若任一接口报错或返回数据中携带message字段则整体进入错误态并显示错误信息if (projectsError || tasksError) { return Container service{service} error{projectsError ?? tasksError} /; } else if (projectsData?.message || tasksData?.message) { return Container service{service} error{projectsData?.message ?? tasksData?.message} /; }四个指标的展示文案由国际化文件提供见 public/locales/en/common.jsonprojects→ Active Projectstasks7d→ Tasks Due This WeektasksOverdue→ Overdue TaskstasksInProgress→ Tasks In Progress其他语言环境可在对应 locale 文件中查看。请求链路与认证流程Vikunja Widget 的数据请求并不是由浏览器直接发往 Vikunja而是经由 Homepage 的 API 代理中转整体链路为前端组件通过useWidgetAPI请求 Homepage 的/api/widgets/...代理端点代理处理器根据widget.type从 src/widgets/widgets.js 注册表中找到vikunja的定义读取其api模板与mappingscredentialedProxyHandler 用formatApiCall拼出{url}/api/v1/{endpoint}并附加Authorization: Bearer key请求头服务端通过httpProxy发起请求拿到数据后经map函数清洗再返回给前端组件渲染。这种代理中转设计有两个好处API Key 不会暴露在浏览器端同时可以统一处理跨域CORS与错误信息脱敏sanitizeErrorURL会移除 URL 中的敏感参数。行为验证测试用例解读仓库为 Vikunja Widget 提供了单元测试可以用来验证上述统计口径src/widgets/vikunja/widget.test.js 校验 widget 配置对象的结构合法性expectWidgetConfigShapesrc/widgets/vikunja/component.test.jsx 使用固定的系统时间2020-01-01T00:00:00Z注入三条模拟任务数据验证加载态下渲染 4 个service-block占位块项目列表中 id 为 -1 的保存筛选器被过滤projects只统计 id 0 的项目两条带真实截止日期的任务均落入tasks7d截止日期早于当前时间的任务被计入tasksOverduepercent_done处于 (0,1) 的任务被计入tasksInProgress。如果你修改或扩展了 Vikunja Widget 的统计逻辑运行pnpm vitest src/widgets/vikunja即可回归验证这些行为。常见问题排查任务数据一直加载不出来优先检查version是否与你部署的 Vikunja 版本匹配。Vikunja v1.0.0-rc4 必须设置version: 2否则tasks/all路径不生效。接口报 401/403确认key是有效的 Vikunja API Key且代理层确实为其附加了Bearer头见 credentialed.js。指标数字与预期不符回顾上文统计口径——项目数不含保存的筛选器id 0本周到期实际是 7 天窗口进行中依赖percent_done开区间。任务列表未显示enableTaskList默认关闭需要显式设置为true且仅展示排序后前 5 条任务。配置好之后将 widget 挂到某个 service 条目下即可在首页看到Active Projects / Tasks Due This Week / Overdue Tasks / Tasks In Progress四个指标配合enableTaskList还能直观掌握最近 5 个待办任务的截止情况让任务管理真正融入你的统一启动页。【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表