Worktile项目管理

  1. 本课程是Worktile的一部分。

  2. 演示

Worktile以项目化的方式计划、管控和跟进多种工作领域和场景中的任务。

项目

任务集合中心,用来计划、组织和跟进一些具有明确目的且相互关联的任务。项目可以是长期的也可以是短期的。

组件

任务的展示方式,将任务信息以不同的视觉形式呈现给用户,有多种组件类型:看板、列表、表格、甘特图、日历、报表。

视图

组件可以有多种视图来对任务进行分组、筛选、排序。

任务类型

承载不同业务场景的模型,由高度结构化的任务属性构成,可规定任务类型之间的关系和状态流转方式,从而形成信息存放和团队协作的规范。

属性:任务类型可以指定此类型的任务可包含哪些自定义信息,有多种属性类型:文本、富文本、数字、日期、成员、多个成员、下拉单选、下拉多选、继承。

任务

某种任务类型的实例。每个任务都有标题、状态,还有负责人、参与人、起止时间、评论等,主体部分是任务类型里定义的各种属性。

建议大家克隆本课程后尝试扩展更多属性类型,甚至扩展组件类型。

项目:

{
    名称: String,
    任务类型: [ID],
    描述: String,
    颜色: String,
    置顶: Boolean,
    参与人: [ID],
    组件: [{
        类型: String,
        名称: String,
        任务类型: ID,
        PC显示: [String],
        视图: [{
            名称: String,
            分组: String,
            筛选: String,
            排序: String
        }]
    }]
}

任务类型:

{
    名称: String,
    项目: ID,
    父任务类型: ID,
    图标: String,
    描述: String,
    状态: [{
        名称: String,
        颜色: String,
        类型: Number,
        默认: Boolean
    }],
    状态流: {},
    属性: [{
        字段: String,
        类型: String,
        选项: [],
        新建: Boolean,
        必填: Boolean
    }]
}

任务:

{
    标题: String,
    项目: ID,
    任务类型: ID,
    父任务: ID,
    关联任务: [ID],
    负责人: ID,
    开始时间: Number,
    截止时间: Number,
    评论: [{
        txt: String,
        auth: ID,
        d: Date
    }],
    状态: {
        名称: String,
        颜色: String,
        类型: Number
    },
    属性: { ... } // 例子如下
}

其中任务属性是存储它所属任务类型属性指定的具体数据,比如招聘任务的属性:

{
    职位: String,
    部门: String,
    薪资范围: String,
    需求人数: Number,
    在职人数: Number,
    JD描述: String,
    参与人: [ID]
}

安装数据库管理插件可以更直观地理解数据模型。

加载项目

  1. 加载我参与的私有项目

  2. 加载公开项目

  3. 把以上两种项目合并后抽取简要信息组成$v.项目.菜单列表

  4. $v.项目.菜单过滤出$v.项目.置顶列表

  5. 如果有$V.s.项目._id就继续加载此项目信息

  6. 加载此项目的任务类型

  7. 加载此项目的所有任务

  8. 恢复此项目的任务栏数组

任务整理

把上面加载的原始数据整理到$v.任务

  1. 如果任务类型里有指定父任务类型,就把它添加到其父任务类型的$v.任务.子任务类型

  2. 把各任务类型里自定义的属性赋给对应的$v.任务.属性列表中

  3. 为了方便读取,继续把上述属性列表根据它里面的字段赋给对应的$v.任务.字段对象中

  4. 不更改原$c常量,克隆所有任务数据赋给$v.任务.arr数组,并根据其_id组成$v.任务.O对象

  5. 如果一个任务有父任务,那就把该任务根据任务类型添加到其父任务的子任务数组x.子任务里,此外递归往上寻找父任务链条组成任务链数组x.父任务arr,作为导航栏展示在任务弹窗顶部

  6. 对于任务类型里定义的继承类型的属性,给其下所有任务里的此属性添加继承字段

分组整理

把上面加载的原始数据整理到$v.分组

  1. 把当前活跃的项目组件(即$V.s.项目.组件)赋给$v.分组.组件

  2. 把当前活跃组件的任务类型下的任务,经过当前活跃视图筛选要求过滤后,根据当前活跃视图规定的分组字段进行分组,把每个任务添加到$v.分组.O[分组属性]数组中,不同的分组属性组成$v.分组.arr数组

  3. 根据任务状态统计各分组下的任务数,并合计分组总数

  4. 根据当前活跃视图的排序要求给各分组里的任务列表进行排序

  5. 把当前任务类型的$v.任务.字段赋给$v.分组.字段

  6. 对甘特图组件做额外处理

任务活动

把任务活动封装成函数,以方便在多个地方任务发生变化时调用:把传入的事件参数添加上变更人和变更时间后插入到任务对应的xtk数组头里。

任务弹窗

从其他页面跳转过来带有“任务”参数时($query.任务)弹出任务模态框。

onResize

当窗体不足以容纳所有组件时把后面的组件/视图收到“更多”里面。 $v.项目.显示表示可以容纳的组件数。

*把上面这些变量打印在控制台查看可以增加感性认识

  1. 项目列表
    搜索

  2. 置顶、取消置顶

  3. 查看归档任务
    激活归档任务

  4. 逻辑删除项目
    添加“删除”字段以放入回收站

  5. 置顶列表

  6. 回收站

  7. 创建项目

  8. 抽屉
    抽屉把手.drawer-handler点击时会切换$V.s.折叠.左菜单的状态从而切换.drawer-wrap的类名drawer-wrap-collapse

  9. 组件列表
    只展示特点个数:组件.slice(0, $v.项目.显示)

  10. 更多组件
    组件.slice($v.项目.显示, 组件.length)
    选中更多列表里的组件时显示组件名称:$V.s.项目.组件 >= $v.项目.显示 ? 组件[$V.s.项目.组件].名称 : "更多"

  11. 视图和更多视图

  1. 新建任务类型与修改任务类型

  2. 属性配置
    属性是保存到数据库中的关于任务的字段。
    预定义属性:当前状态、负责人、开始时间、截止时间

  3. 添加自定义属性
    “属性类型”决定了属性的展示方式,选定后不可更改。
    如有“父任务类型”则添加“继承”属性,有专属的“源属性名称”下拉框以选择可继承属性,包括父任务类型的预定义属性和自定义属性,继承可递归/追溯到顶级祖宗任务。

  4. 定义自定义属性
    选中一个自定义属性后配置其属性。
    “属性名称”是展示和保存到数据库的字段名,下拉框有选项列表,打开“展示在新建页上”开关会在“新建任务”弹窗中展示,并出现“必填”选项,“必填”开关会在属性名前添加红色星号,并在入库前检查是否已填。

  5. 排序与删除自定义属性

  6. 状态配置
    状态列表决定了一个任务的所有可能的状态。
    状态有名称、颜色、类型和备注。
    状态有3中类型:未开始、进行中、已完成,决定了任务分组中的进度条的3种颜色。
    初始状态是新建任务的默认状态,所以只可能有一个初始状态。

  7. 状态流
    状态流是指特定状态可变更成哪种几种状态,未勾选或已清除状态流则一个状态可以变更成任何一种状态。

  8. 添加、编辑、移除、保存状态

  1. 添加、编辑、删除、排序组件
    每种任务类型可以添加多种不同形式的组件
    但报表组件与任务类型无关,一个项目也只需要一个报表组件

  2. 组件视图
    每个组件可以有各种不同视图,定义其分组、筛选、排序的方式。
    编辑、添加、删除

  3. PC显示
    定义在PC端显示任务列表时应该显示哪些属性
    添加、删除、排序要显示的属性

  4. 看板
    看板的主要特点是可以拖拽分组或排序
    拖拽一个任务到另一个分组时要修改其分组的字段到新组名
    拖动这个分组以排序会把组名列表存入到视图的”组名arr“数组里
    当打开右下角的”拖拽排序“开关时会触发旁边的挂载组件里的表达式,加载并配置SmoothDnD库。

  5. 表格、列表
    两者类似,区别在于表格用table呈现,把字段名展示在表格头,列表用div呈现,字段名和它的值放在一起展示。

  6. 日历
    日历用的是FullCalendar插件,在挂载组件里的表达式里加载并配置。

  7. 甘特图
    下面专节讲解

  8. 报表
    有个挂载组件加载highcharts插件并初始化$v.任务.状态$v.任务.任务类型
    每个图表都是直接渲染在各自的挂载组件$el上面,在$obj.option里定义其动态选项,在挂载事件里添加动态数据。
    点击每个数量都会弹窗展示其任务列表。

  1. 挂载时初始化$v.甘特
    move函数:每调用一次都会在时间轴添加一周,传入负值时就把时间轴往左延伸,轴 - 7,正值便往右,轴 + 7,在队首或队尾推入新增的一周(包括年月日信息)。
    日期计算比月份复杂点,我们以当周的星期几为基点,前面的日期推入队首(unshift),后面的日期推入队尾(push)。值得注意的是延伸过程中日期有可能是小于0或者大于本月最大天数,那就意味着日期跨月份了,小了就要加上上月天数,大了要减去本月天数。
    月:也包含年份,用来渲染年月轴
    日:用来渲染日期轴
    首日:用来计算任务条和今日线(gantt-today-line)的left样式

  2. 延伸时间轴
    挂载时预先以今日为中心向前后各延伸了10周,同时在年月轴两边各放置了一个交叉观察器,当用户滚到它那里时自动继续延伸4周。$v.甘特.inited用来避免还未初始化就触发滚动。

  3. hover
    鼠标挪到左边固定栏的任务上时(onMouseOver)会把对应的任务条滚入可视范围(scrollIntoViewIfNeeded)。
    鼠标挪到任务条上时展示任务概要信息和前后拖拽手柄。

  4. 拖拽
    拖动任务条本体和前后拖拽手柄都能够更改任务的开始时间和(或)截止时间,同时动态显示拖拽层(gantt-drag-mask)的可视化效果。
    鼠标按下时开始监听鼠标移动事件,鼠标松开时根据移动距离/偏移量修改开始时间和(或)截止时间。
    拖拽任务条本体时如果未发生位移应该认为是点击动作从而弹窗展示任务详情

  1. 新建任务
    A. 在看板、表格、列表类型的组件的右上角都有个“新建”按钮用来新建无预设任务
    B. 每个分组都有个加号按钮用来添加同组新任务:在$f.创建任务的挂载事件中将把$v.modal.分组赋给用来分组的字段中,如果该字段是状态则进一步过滤出可能的状态选项,有父任务类型时也同理;
    C. 在任务弹窗中,如果允许有子任务类型,则可以在其某个子任务标签栏里新建子任务,此时预设了父任务。

  2. 本组任务进度占比
    每组任务上方都有个进度条,分别表示本组已完成、进行中、未开始的任务数及其占比。

  3. 任务弹窗顶部
    由项目名、任务类型、父任务arr数组、当前任务标题及各自图标和颜色组成。
    每节父任务可点击展示其详情。

  4. 分享到聊天

  5. 固定到任务栏
    $v.任务栏是当前项目固定的任务列表,可展开收缩,可移除可点击弹出详情。

  6. 归档任务

  7. 删除任务
    同时也要删除其关联的一个任务活动和多个资源。
    把所有关联资源搜索出来,把返回来的arr克隆一下再依次删除:
    $r.arr.clone().forEach('$resource.delete($x._id)')

  8. 标题
    点击切换到编辑模式并聚焦,失去焦点或按下回车时保存修改并切换回展示模式。

  9. 当前状态
    展示名称、图标和颜色
    点击弹出当前状态下一个可流转的状态选项

  10. 负责人、开始时间、截止时间

  11. 基本信息
    展示的是当前任务类型的自定义属性及其在此任务中的值。
    分别根据各自的属性类型来展示,通常分3列展示,但富文本和多行文本独占一行。

  12. 子任务标签栏及其列表
    可点击展示,可解除关联、删除任务,可变更负责人和截至日期

  13. 关联任务
    相关又非直接子任务

  14. 附件
    任务弹窗的顶层是个挂载组件,会把关联资源搜索出来,虽然一开始不展示附件列表但也是要展示附件数量的。
    添加,重命名,删除
    附件图标可能是上去前的本地文件预览图thumb,也可能是资源上传后的缩略图,还可能是根据其文件类型预设的文件图标。

  15. 评论

  16. 活动
    因为用户点击的时候才展示,所以可以延缓加载,单独存放于关联xtk中,没必要像评论一样存于任务中。

日期选择器是比较常用的功能,也有点小复杂,本来可以选一个开源的js库直接使用的,刚开始的时候为了验证表达式的能力就直接写了。

  1. 弹出日期选择器前先初始化$v.pop
    keep:为保持点击弹框本身不关框,参考$c.exp.onLogin里添加的一个全局click事件
    date:当前已设日期/时间,如果没有就会是今天
    time:是否需要设置时间,如果上面的date里包含了分钟/秒钟则默认为真
    F5:目的是再次触发日期选择器里的挂载事件从而重新初始化$v.日期
    cb:选中/清除日期是调用的回调函数,它会做“截止时间不能早于开始时间”的验证后保存/清除对应日期。

  2. 日期选择器顶层是个挂载组件用以构造$v.日期
    F5函数:根据$v.日期里的构造那个月份的日期数组$v.日期.arr,每次挂载或年份、月份发生变化时都要调用。
    日期数要比一个月的天数多,用的是6周,也即6 * 7的二维数组,所以有前头有部分日期是上个月的,后头有部分是下个月的。我们以本月第一个星期几作为起点,小于它的是上个月的,月份 - 1,日期 + 上月天数;大于本月天数的是下个月的,月份 + 1,日期 - 本月天数。
    另外13月份是明年的1月,0月份是去年12月。

  3. 返回日期
    如果需要设置时间则必须点“确定”按钮才返回由年月日时分构造的date,点选日期只是更新$v.日期里的月和日。
    如果不需要设置时间点选日期则会立即返回由选中年月日构造的date。

  4. 清除
    如果需要设置时间“清除”按钮只是关闭时间设置表单
    如果不需要设置时间则会立即返回空以便调用者清除此日期

  5. 快速输入时间
    除了直接在输入框直接输入小时分钟数外可以点击输入框上方或下方的箭头进行加减,甚至直接按键盘上的上下箭头键进行快速加减。为提高效率,分钟数是以5为单位进行加减的。
    注意在加减过程中小时分钟数超出范围时的特殊处理。

  6. 加减年份/月份
    顶部有双箭头加减年份,单箭头图标可加减月份。注意月份可能会翻到去年或明年时的检查。

  7. 快速选择跨度大的年份/月份
    当需要选择较远的年份时用上面的箭头一步步加减有点慢,比如选择一个老人的出生年月日,此时点击顶部中央的年月可以直接选择月份,再点击顶部中央的年份可以以20年为单位快速定位年份。

Make in ZC APP Platform