ARTICLE DETAIL

资讯详情

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

WeKan 列表(Lists)机制详解:看板列的作用域、归档删除与共享/个人宽度系统

WeKan 列表(Lists)机制详解:看板列的作用域、归档删除与共享/个人宽度系统 WeKan 列表Lists机制详解看板列的作用域、归档删除与共享/个人宽度系统【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan本文以 WeKan 官方功能文档 Lists 为主体完整覆盖列表List作为看板列的核心概念、跨泳道共享规则、添加/归档/删除操作流程以及列表宽度系统的共享模式与个人模式并结合 models/lists.js、models/lib/listWidth.js、client/components/lists/list.js 等源码说明宽度解析链路、权限控制与软删除实现帮助你在实际运维和二次开发中准确理解 WeKan 列表的数据模型与渲染规则。列表是什么看板的列且全看板共享列表Lists就是看板的列columns卡片随着工作推进在列表之间移动。WeKan 中列表最重要的作用域规则是列表属于整个看板而不是某一条泳道。具体含义同一个列表会出现在看板的每一条泳道swimlane中——所有泳道共享同一组列一张卡片同时属于一个列表和一个泳道泳道是它的水平带状区域WeKan **没有“每个泳道各自一套列表”**的功能。历史上曾实验过让每条泳道拥有独立列表的方案issue #4049但由于该方案会在每条泳道重复列、并导致卡片意外移动最终被回退兜底修复机制如果某个列表因异常数据被绑定到了单条泳道从而从其他泳道中消失看板打开时的修复逻辑会把它重新共享到所有泳道相关说明见 Repairs。从源码结构看这一“全看板共享”特性对应列表文档中的swimlaneId字段在 models/lists.js 的 schema 中swimlaneId是可选字段defaultValue: 空值即表示该列表为看板级列表。同文件中cards(swimlaneId)等 helper见 models/lists.js展示了列表在给定泳道上下文中如何筛选卡片不传泳道时返回整个列表的卡片传入非首泳道时只返回该泳道的卡片孤儿卡片指向已删除泳道统一浮现在第一条泳道。添加、归档、恢复与删除列表官方文档给出的四个操作添加Add在看板侧边的列表输入区list composer新建列表归档Archive把列表隐藏而不删除归档后的列表可以恢复恢复Restore把归档的列表重新显示出来删除Delete永久删除列表。删除不可撤销——WeKan 有意设计了更多点击步骤来防止误删。官方提示Tip日常应使用“归档”卡片/列表以便日后恢复。如果想快速删除大量卡片可以把它们拖到一个新建的列表里然后删除该列表。删除不可撤销——多余的操作步骤是刻意设计的。早期版本存在一个容易被误点的删除按钮导致用户误删重要列表后来被专门修复。源码层面的对应实现models/lists.jsasync archive() { // 模板列表board template归档时会级联归档其中所有卡片 if (this.isTemplateList()) { for (const card of await this.cards()) { await card.archive(); } } return await Lists.updateAsync(this._id, { $set: { archived: true, archivedAt: new Date() } }); }, async restore() { // 模板列表恢复时级联恢复所有卡片 if (this.isTemplateList()) { for (const card of await this.allCards()) { await card.restore(); } } return await Lists.updateAsync(this._id, { $set: { archived: false } }); },归档状态由两个字段承载archived布尔值默认false见 models/lists.js和archivedAt最近一次归档时间。值得注意的区分是archived是“可见的搁置状态”有独立的归档界面而“删除”则走软删除路径——schema 中的deletedAt/deletedBy/deleteBatchId字段见 models/lists.js标记被删除的列表deleteBatchId把列表和随之删除的卡片归为一组以便恢复时精确还原这一整组对象这正是 WeKan 撤销/恢复能力#1023在列表上的落地方式。列表宽度两种调整方式每个列表只有一个宽度值。官方文档给出两种修改途径拖拽拖动列表右边缘的调宽手柄resize handle输入打开列表菜单 →Set width输入以像素为单位的宽度。关于宽度数值文档原文写的是最小 270 px、默认 272 px。需要注意当前仓库源码中的实际取值已更新源码注释引用了 issue #6465/#6409 的改动以源码为准常量位置当前值说明DEFAULT_LIST_WIDTHmodels/lib/listWidth.js220 px所有未自定义列表的渲染默认宽度由 272 收窄到 220让屏幕能放下更多列MIN_LIST_WIDTHmodels/lib/listWidth.js200 px拖拽手柄与校验的最小宽度随默认值一起下调schema 校验范围models/lists.js100–1000 pxlists.width超出范围会触发widthOutOfRangeschema 默认值同为 220models/lib/listWidth.js是宽度逻辑的单一事实来源single source of truth。它存在的背景是 issue #5659此前默认宽度分散在客户端列表组件、列表头、schema 和用户模型多处取值互相矛盾272/270 混用导致同一看板上不同访问路径解析出不同宽度公开看板的匿名访客表现最明显。该模块刻意写成不依赖 Meteor 的纯函数可以在纯 Node 环境下单元测试对应 tests/listWidthDefaults.test.cjs。宽度解析的核心函数resolveListWidthmodels/lib/listWidth.js定义了清晰的回退顺序function resolveListWidth(options) { const { fixedEnabled false, fixedWidth null, sharedWidth null, personalMode false, personalWidth null, } options || {}; if (fixedEnabled) { return normalizeListWidth(fixedWidth); // 1) 固定宽度模式所有列表同一宽度 } const shared normalizeListWidth(sharedWidth); if (!personalMode) { return shared; // 2) 共享模式直接用 lists.width } return normalizeListWidth(personalWidth, shared); // 3) 个人模式个人值 → 共享值 → 默认值 }客户端入口在 client/components/lists/list.js 的effectiveListWidth(list)它按当前查看者收集“固定宽度、共享宽度list.width、个人模式开关、个人宽度”四项输入然后交给resolveListWidth决定最终像素值——没有任何自定义时永远返回DEFAULT_LIST_WIDTH这保证了公开看板上所有列表默认同宽。拖拽调宽的实现位于同一文件的initializeListResizeclient/components/lists/list.js手柄是.js-list-resize-handle元素拖拽过程中实时设置--list-width/width等 CSS 变量松手时以Math.max(minWidth, startWidth deltaX)钳制最小值后调用saveListWidth持久化该逻辑同时绑定了鼠标事件和原生touchstart/touchmove/touchend{ passive: false }支持移动端拖拽调宽。折叠collapsed状态的列表按设计不渲染调宽手柄。共享宽度 vs 个人宽度#6409一个看板级设置控制“改宽度影响谁”。在看板侧边栏的“Show at all boards page”设置区切换Personal list widths开关对应模板 client/components/sidebar/sidebar.jadei18n 文案见 imports/i18n/data/en.i18n.json 的personal-list-width键关闭默认— 共享Shared宽度存储在列表文档本身的lists.width字段上看板上所有人看到同一布局只有具备写权限的成员才能修改宽度只读/仅评论成员看不到调宽手柄。源码中的判定函数canResizeListclient/components/lists/list.js在共享模式下最终返回Utils.canModifyBoard()宽度随看板一起导出/导入迁移。开启 — 个人Personal每个用户保存自己的宽度登录用户存在用户 profile未登录访客存在浏览器 localStorage键名为wekan-list-widths见 client/components/lists/list.js个人宽度未设置时回退到共享宽度再回退到默认值个人模式下任何查看者都可以拖拽调宽canResizeList直接返回true因为改动只影响自己的视图。该开关在看板文档上的字段是boards.allowsPersonalListWidthmodels/boards.js切换事件在 client/components/sidebar/sidebar.js 中处理REST API 也暴露了这个字段public/api/wekan.yml。共享模式下宽度的服务端写入走Meteor.call(applyListWidth, ...)由服务端再次校验看板成员身份见 client/components/lists/list.js 与 server/models/users.js 中applyListWidth的实现。源码补充宽度系统中还存在的两种“同宽”模式从源码结构看除了文档描述的共享/个人两种模式当前代码还实现了两种“所有列表统一同宽”的模式它们都位于effectiveListWidth的解析链路中且优先级高于个人宽度查看者个人的固定宽度#5729isFixedListWidth按查看者、按看板开启让该查看者的所有列表渲染成同一宽度并持久化到 profile 或 localStoragewekan-fixed-list-width*键看板级的固定宽度#6680boards.sameWidthForAllLists/sameWidthForAllListsValue见 models/boards.js由管理员在顶部栏设置对所有查看者生效覆盖任何成员的个人偏好另有listWidthResizeLockedmodels/boards.js可在开启期间锁定所有人的拖拽调宽。对应的端到端验证在 tests/playwright/specs/38-fixed-list-width.e2e.js。自动宽度Auto-width不指定固定宽度也可以让列表按内容自适应auto-width打开列表菜单 →Set width→Auto list width开关。自动宽度作用于看板的所有列表并且与固定宽度遵循同样的作用域规则共享模式下它是看板级设置字段boards.autoWidthmodels/boards.js由有写权限的成员修改所有人看到同样的结果个人模式下它是按用户的存储在各用户的profile.autoWidthBoards。判定逻辑见 client/components/lists/list.jsfunction effectiveAutoWidth(boardId) { if (isPersonalListWidth(boardId)) { const user ReactiveCache.getCurrentUser(); return !!(user user.isAutoWidth(boardId)); // 个人模式读个人 profile } const board ReactiveCache.getBoard(boardId); return !!(board board.autoWidth); // 共享模式读看板字段 }自动宽度开启时固定宽度的输入框和拖拽手柄都会被隐藏canResizeList在effectiveAutoWidth为真时直接返回false避免两种宽度来源互相覆盖。需要说明的历史变更此前每个列表上“最小宽度 / 最大宽度”的像素选项已被移除——列表现在只有一个明确的宽度固定或自动能可靠地在刷新后持久保留。这一简化正是 #6409 引入的“单一宽度模型”文件头部的注释client/components/lists/list.js对此有明确记录。列表的数据模型速览结合 models/lists.js 的 SimpleSchema列表文档的核心字段字段类型/约束说明titleString必填列表标题boardIdString必填所属看板swimlaneIdString默认所属泳道空表示看板级列表archived/archivedAtBoolean / Date归档状态与最近归档时间deletedAt/deletedBy/deleteBatchIdDate / String / String软删除标记deleteBatchId关联同批删除的卡片sortNumber列表在看板中的排序starredBoolean默认false星标后置顶wipLimit.{value,enabled,soft}对象WIP 限制默认值 1、关闭、硬限制详见 WIP LimitscolorString可选命名列表色板色或自定义#rrggbb十六进制#5514校验逻辑见 models/lists.jstypeString默认listlist或template-list看板模板列表widthNumber默认 220范围 100–1000共享宽度见上文syncSource.{type,url,projectKey,...}对象可选外部跟踪器Jira/GitHub/GitLab/Gitea同步来源元信息由 server/listSync.js 的定时任务维护凭据不存这里而在服务端私有集合 models/listSyncCredentials.jscreatedAt/updatedAt/modifiedAtDate时间戳updatedAt在插入/更新/上插时自动刷新相关文档WIP LimitsSwimlanesArchive and DeleteRepairs【免费下载链接】wekanThe Open Source kanban, built with Meteor. GitHub issues/PRs are only for FLOSS Developers, not for support, support is at https://wekan.fi/commercial-support/ . PR source translation to imports/i18n/data/en.i18n.json, other translations at https://app.transifex.com/wekan/wekan项目地址: https://gitcode.com/GitHub_Trending/we/wekan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表