Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

teambition-sdk

teambition8.1kMIT0.12.95TypeScript support: included

Front-End SDK for Teambition

teambition, sdk, teambition-sdk

readme

CircleCI Coverage Status Dependency Status devDependency Status

isomorphic-sdk for Teambition APIs

设计理念

SDK 主要解决的是数据同步的问题。通俗点讲,就是在前端使用数据模型模拟出数据库的增删改查等操作。

为什么会有这种需求? 以 https://api.teambition.com/tasks/:_id 为例, Teambition 的 API 会返回下面格式的数据:

{
  "_id": "001",
  "name": "task",
  "executor": {
    "_id": "002",
    "name": "executor 1",
    "avatarUrl": "https://xxx"
  },
  "subtasks": [
    {
      "_id": "003",
      "name": "subtask",
      "executor": {
        "_id": "004",
        "name": "executor 2",
        "avatarUrl": "https://xxx"
      }
    }
  ]
}

而倘若这个任务中包含的子对象,比如 executor 字段对应的数据通过其它 API 进行了变更:

/**
 * @url https://api.teambition.com/subtasks/:_id
 * @method put
 * @body {name: 'executor test'}
 */
SubtasksAPI.update('002', {
  name: 'subtask update'
})
  .subscribe()

在前端,需要自行处理与此 subtask 相关的所有变更情况。例如:

  1. 包含这个子任务的列表中的这个子任务名字的变更。
  2. 包含这个子任务的任务的详情页中,该子任务名字的变更。

然而在现有的 Teambition 数据模型中,需要在每一个 Model 或者 Collection 或者 View 中手动监听与自己相关联的数据,例如:

// 匹配第一种情况
class MyTasksView extends Backbone.View {
  ...
  listen() {
    this.listenTo(warehouse, ':change:task', model => {
      // handler
    })
    this.listenTo(warehouse, ':change:subtask', model => {
      // handler
    })
  }
}
// 匹配第二种情况

class SubtaskCollection extends Backbone.Collection {
  ...

  constructor() {
    this.on('add destroy remove change:isDone', () =>
      Socket.trigger(`:change:task/${this._boundToObjectId}`, {
        subtaskCount: {
          total: this.length
          done: this.getDoneSubTaskCount()
        }
      })
    )
  }
  getDoneSubTaskCount() {
    this.where({isDone: true}).length
  }
}

class TaskView extends Backbone.View {
  ...
  listen() {
    this.listenTo(this.taskModel, 'change', this.render)
  }
}

而在当前的设计中,所有的这种变更情况都在数据层处理,视图/业务 层只需要订阅一个数据源,这个数据源随后的所有变更都会通知到订阅者。 比如获取一个任务:

import 'rxjs/add/operator/distinctUntilKeyChanged'
import { TasksAPI } from 'teambition-sdk'
import { Component, Input } from '@angular/core'

@Component({
  selector: 'task-detail',
  template: `
    <div> {{ task$?.name | async }} </div>
    <div> {{ subtaskCount$ | async }} </div>
  `
})
export default class TaskView {

  @Input('taskId') taskId: string

  private task$ = this.TaskAPI.get(this.taskId)
    .publishReplay(1)
    .refCount()

  private subtaskCount$ = this.task$
    .distinctUntilKeyChanged('subtasks')
    .map(task => ({
      total: task.subtasks.length,
      done: task.subtasks.filter(x => x.isDone).length
    }))

  constructor(
    private TasksAPI: TasksAPI
  ) { }
}

如果更加纯粹的使用 RxJS,甚至可以组合多种数据和业务:

import 'rxjs/add/operator/distinctUntilKeyChanged'
import 'rxjs/add/operator/distinctUntilChanged'
import { PermissionAPI, TasksAPI, ProjectAPI } from 'teambition-sdk'
import { Component, Input } from '@angular/core'
import * as moment from 'moment'
import { errorHandler } from '../errorHandler'

@Component({
  selector: 'task-detail',
  template: `
    <div [ngClass]="{'active': permission$.canEdit | async}"></div>
    <div> {{ task$?.name | async }} </div>
    <div> {{ subtaskCount$ | async }} </div>
    <div> {{ dueDate$ | async }} </div>
  `
})
export default class TaskView {

  @Input('taskId') taskId: string

  private task$ = this.TaskAPI.get(this.taskId)
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

  private subtaskCount$ = this.task$
    .distinctUntilKeyChanged('subtasks')
    .map(task => ({
      total: task.subtasks.length,
      done: task.subtasks.filter(x => x.isDone).length
    }))

  private dueDate$ = this.task$
    .map(task => moment(task.dueDate).format())

  private project$ = this.task$
    .distinctUntilKeyChanged('_projectId')
    .switchMap(task => this.ProjectAPI.get(task._projectId))
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

  private permission$ = this.task$
    .distinctUntilChanged((before, after) => {
      return before._executorId === after._executorId &&
        before._projectId === after._projectId
    })
    .switchMap(task => {
      return this.project$
        .distinctUntilKeyChanged('_defaultRoleId')
        .switchMap(project => {
          return this.PermissionAPI.getPermission(task, project)
        })
    })
    .catch(err => errorHandler(err))
    .publishReplay(1)
    .refCount()

  constructor(
    private TasksAPI: TasksAPI,
    private PermissionAPI: PermissionAPI
  ) { }
}

在这种场景下,关于 task 的任何变更 (tasklist 变更,executor 变更,stage 变更等等,权限变化) 都能让相关的数据自动更新,从而简化 View 层的逻辑。

changelog

Change Log

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

0.6.27 (2018-07-20)

Bug Fixes

  • 移除不再使用的 isInbox 字段 (edda72f)

0.6.26 (2018-07-18)

Bug Fixes

  • sockets: 修复“双//路径”问题 (3361af3)

0.6.25 (2018-07-11)

Bug Fixes

  • 解决 mock 构建失败问题,避免直接引入 srctest 模块 (5530b19)

0.6.24 (2018-07-10)

Features

  • TaskAPI: 添加 updateRating() 接口 (d8c9d59)

0.6.23 (2018-05-10)

Bug Fixes

  • 允许 Socket 地址带有 path 参数 (dbf6b1d)

0.6.22 (2018-05-08)

Bug Fixes

  • schemas/UserMe: 使用 userMe.tcmToken 连接 WebSocket 服务 (34dd51a)

0.6.21 (2018-04-27)

Bug Fixes

  • apis/CustomFieldAPI: 确保将 updateTaskCustomField() 返回结果存入缓存 (c32d44a)

Features

  • apis/ScenarioFieldConfigAPI: 添加 getScenarioFieldConfigs() 接口 (18295d5)
  • apis/TagAPI: 添加 getTags() 接口 (078a8b7)
  • apis/TaskAPI: 添加 updateStartDate() 接口 (c2e398b)

0.6.20 (2018-04-26)

Bug Fixes

  • api/CustomFieldAPI: 更正 CustomFieldAPI 命名 (d20831a)

0.6.19 (2018-04-26)

Bug Fixes

  • apis/CustomFieldLinkAPI: 确保 CustomFieldLinkApi 被导出 (b8e95d9)

0.6.18 (2018-04-26)

Features

  • apis/CustomFieldLinkAPI: 添加 getProjectCustomFieldLinks() 接口 (161d6ea)
  • apis/TaskAPI: 添加 getMyTasksByType() 接口 (6d05817)

0.6.17 (2018-04-25)

Bug Fixes

  • schemas/schema: 明确变量类型,避免 noImplicitAny 问题 (fc1670c)

0.6.16 (2018-04-25)

Bug Fixes

  • schemas: 更新 Task 定义,添加 TaskflowStatus 定义 (36647a3)

0.6.15 (2018-04-23)

Bug Fixes

  • schemas/Project: 导出 ProjectApplication 定义 (ee159c2)

0.6.14 (2018-04-23)

Bug Fixes

  • schemas: 更新 OrganizationProject 定义 (ada00c5)

0.6.13 (2018-04-18)

Bug Fixes

  • schemas/Member: 更新定义,修复相关测试 (df76110)
  • storage/Database: 避免“‘并行请求’致使‘Collection 重复创建’而导致数据无法更新”问题 (2189e6f)

0.6.12 (2018-04-13)

Bug Fixes

  • fetchs/TaskFetch: 校正“收藏”相关接口返回值 (8e2db2d)
  • schemas/Member: 更新定义 (00c2953)
  • schemas/UserMe: 更新定义 (8e794ad)