diff --git a/app/assets/javascripts/gitee-frontend/components/boards.js b/app/assets/javascripts/gitee-frontend/components/boards.js
index add347982609800869ca4e7e6788b3a77e22d326..7ccb38ad9a30331fee614654397af9346d62b687 100644
--- a/app/assets/javascripts/gitee-frontend/components/boards.js
+++ b/app/assets/javascripts/gitee-frontend/components/boards.js
@@ -1,1067 +1,1971 @@
/*!
- * Gitee-Frontend.js v0.17.1
- * (c) 2019 Liu Chao
+ * Gitee-Frontend.js v0.22.0
+ * (c) 2021 Gitee
* Released under the MIT License.
*/
(function () {
- 'use strict';
-
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- };
-
- var createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
-
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
-
- var inherits = function (subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- }
-
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- };
-
- var possibleConstructorReturn = function (self, call) {
- if (!self) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
-
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
- };
-
- var defaults$1 = {
- readonly: false,
- key: 'state',
- name: 'board',
- message: {
- loading: 'loading ...',
- stateDisabled: 'Current issue cannot switch to this state',
- allComplete: 'Showing all issues',
- empty: 'There are no issues here',
- btnSetFirst: 'Move it to the first',
- btnSetLast: 'Move it to the last'
- },
- className: {
- iconComment: 'icon comments outline',
- iconAngleLeft: 'icon angle double left',
- iconAngleRight: 'icon angle double right',
- iconIssue: 'icon sticky note outline',
- card: 'ui link card',
- action: 'ui button',
- actions: 'ui mini basic icon buttons',
- avatar: 'ui avatar image'
- },
- actions: function actions(config) {
- if (!config.plugins.Sortable) {
- return [];
- }
- return [{
- id: 'btn-set-first',
- class: config.className.action,
- icon: config.className.iconAngleLeft,
- title: config.message.btnSetFirst,
- callback: function callback(boards, board) {
- var state = board.state.toString();
- var states = boards.sortable.toArray();
- var i = states.indexOf(state);
-
- if (i >= 0) {
- states.splice(i, 1);
- states.splice(0, 0, state);
- boards.sortable.sort(states);
- config.onSorted(states);
- boards.load();
- }
- }
- }, {
- id: 'btn-set-last',
- class: config.className.action,
- icon: config.className.iconAngleRight,
- title: config.message.btnSetLast,
- callback: function callback(boards, board) {
- var state = board.state.toString();
- var states = boards.sortable.toArray();
- var i = states.indexOf(state);
-
- if (i >= 0) {
- states.splice(i, 1);
- states.push(state);
- boards.sortable.sort(states);
- config.onSorted(states);
- boards.load();
- }
- }
- }];
- },
-
- data: [{
- order: 1,
- name: 'Backlog',
- state: 'open',
- color: '#ffa726',
- issuesCount: 0
- }, {
- order: 2,
- name: 'Done',
- state: 'closed',
- color: '#2baf2b',
- issuesCount: 0
- }],
- plugins: {},
- types: [],
- user: {
- id: 0,
- admin: false
- },
-
- /**
- * 在任务列表加载完后的回调
- * @callback BoardLoadCallback
- * @param {Array} issues 任务列表
- * @param {Number} count 任务总数
- */
-
- /**
- * 在开始加载任务列表时的回调
- * @param {Object,Board} board 板块对象
- * @param {BoardLoadCallback} callback 用于接收任务列表的回调函数
- */
- onLoad: function onLoad(board, callback) {
- $.ajax({
- url: 'issues',
- data: {
- state: board.state,
- page: board.page
- }
- }).done(function () {
- callback([], 0);
- }).fail(function () {
- callback([], 0);
- });
- },
-
- /**
- * 在更新任务时的回调
- * @param {Object} issue 任务
- * @param {String,Number} oldState 更新前的状态
- */
- onUpdate: function onUpdate(issue, oldState) {
- var _this = this;
-
- $.ajax({
- type: 'PUT',
- url: issue.url,
- data: {
- state: issue.state
- }
- }).done(function (res) {
- _this.updateIssue(res);
- }).fail(function () {
- _this.setIssueState(issue.id, oldState);
- });
- },
-
- /**
- * 在渲染任务卡片时的回调
- * @param {Object} issue 任务
- * @param {JQuery} $el 任务卡片
- */
- onRender: function onRender(issue, $el) {
- $el.addClass('issue-state-' + issue.state);
- return $el;
- },
-
- /**
- * 在板块被排序后的回调
- * @param {Array} states 状态列表
- */
- onSorted: function onSorted(states) {
- window.console.log(states);
- }
- };
-
- var Config = function Config(config) {
- classCallCheck(this, Config);
-
- $.extend(this, defaults$1, config);
- if (config.className) {
- this.className = $.extend({}, defaults$1.className, config.className);
- }
- if (config.message) {
- this.message = $.extend({}, defaults$1.message, config.message);
- }
- };
-
- var htmlSafe = function () {
- var $el = $('
');
-
- return function (text) {
- return $el.text(text).html();
- };
- }();
-
- var Renderer = function () {
- function Renderer(config) {
- classCallCheck(this, Renderer);
-
- this.config = config;
- }
-
- createClass(Renderer, [{
- key: 'getAvatarUrl',
- value: function getAvatarUrl(name, avatarUrl) {
- var Avatar = this.config.plugins.LetterAvatar;
- if (!avatarUrl || avatarUrl.indexOf('no_portrait.png') === 0) {
- if (Avatar) {
- return Avatar(name);
- }
- }
- return avatarUrl;
- }
- }, {
- key: 'getCardId',
- value: function getCardId(issue) {
- if (this.config.getIusseId) {
- return this.config.getIusseId(issue);
- }
- return 'issue-card-' + issue.id;
- }
- }]);
- return Renderer;
- }();
-
- /* eslint-disable indent */
-
- function getUserUrl(user) {
- return user.html_url || user.path;
- }
-
- function renderCardUserLabel(issue) {
- if (!issue.author) {
- return '';
- }
- if (typeof issue.author.is_member !== 'undefined') {
- if (!issue.author.is_member) {
- return '[访客]';
- }
- }
- if (issue.author.outsourced) {
- return '[外包]';
- }
- return '';
- }
-
- function renderCardLabels(issue) {
- var html = '';
-
- if (!issue.labels) {
- return '';
- }
-
- issue.labels.forEach(function (label) {
- html += ['', htmlSafe(label.name), ''].join('');
- });
- return '' + html + '
';
- }
-
- var CardRenderer = function (_Renderer) {
- inherits(CardRenderer, _Renderer);
-
- function CardRenderer() {
- classCallCheck(this, CardRenderer);
- return possibleConstructorReturn(this, (CardRenderer.__proto__ || Object.getPrototypeOf(CardRenderer)).apply(this, arguments));
- }
-
- createClass(CardRenderer, [{
- key: 'render',
- value: function render$$1(issue) {
- var user = this.config.user;
- var readonly = this.config.readonly;
-
- var draggable = '';
- var cardClass = this.config.className.card;
-
- if (!readonly && (user.admin || user.id === issue.author.id)) {
- draggable = 'draggable="true"';
- cardClass += ' card-draggable';
- }
- return ['', '', '', '
', '', ''].join('');
- }
- }, {
- key: 'renderState',
- value: function renderState(issue) {
- var state = issue.state_data;
-
- if (!state || this.config.key === 'state') {
- return '';
- }
- return ['', '', '
'].join('');
- }
- }, {
- key: 'renderAssignee',
- value: function renderAssignee(issue) {
- var user = issue.assignee;
-
- if (!user || !user.id || this.config.key !== 'state') {
- return '';
- }
- return [''].join('');
- }
- }, {
- key: 'renderComments',
- value: function renderComments(issue) {
- var className = this.config.className.iconComment;
-
- if (!issue.comments) {
- return '';
- }
- return '');
- }
- }]);
- return CardRenderer;
- }(Renderer);
-
- /* eslint-disable no-plusplus */
-
- function setColorAlpha(color, alpha) {
- var reg = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
- var matches = reg.exec(color);
- var r = parseInt(matches[1], 16);
- var g = parseInt(matches[2], 16);
- var b = parseInt(matches[3], 16);
- return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
- }
-
- function renderBoardIcon(board) {
- var iconStyle = '';
-
- if (board.color) {
- iconStyle = 'style="color: ' + board.color + '"';
- }
- if (board.icon) {
- return '';
- }
- return '';
- }
-
- var BoardRenderer = function (_Renderer) {
- inherits(BoardRenderer, _Renderer);
-
- function BoardRenderer() {
- classCallCheck(this, BoardRenderer);
- return possibleConstructorReturn(this, (BoardRenderer.__proto__ || Object.getPrototypeOf(BoardRenderer)).apply(this, arguments));
- }
-
- createClass(BoardRenderer, [{
- key: 'render',
- value: function render$$1(board) {
- return ['', '
', this.renderHeader(board), '
', '
', '
', '
', '
', '
', this.config.message.stateDisabled, '
', '
', '
', '
', '
'].join('');
- }
- }, {
- key: 'renderHeader',
- value: function renderHeader(board) {
- var headerStyle = '';
- var headerClass = 'board-header';
-
- if (board.color) {
- if (board.colorTarget === 'background') {
- headerStyle = 'background-color: ' + setColorAlpha(board.color, 0.04);
- } else {
- headerClass += ' has-border';
- headerStyle = 'border-color: ' + board.color;
- }
- }
- return [''].join('');
- }
- }, {
- key: 'renderActions',
- value: function renderActions() {
- var config = this.config;
- var actions = config.actions;
-
- if (typeof actions === 'function') {
- actions = actions(config);
- }
- return ['', actions.map(function (a) {
- return [''].join('');
- }).join(''), '
'].join('');
- }
- }, {
- key: 'renderAvatar',
- value: function renderAvatar(board) {
- if (!board.avatarUrl) {
- return '';
- }
- return ['
'].join('');
- }
- }, {
- key: 'renderTip',
- value: function renderTip(board) {
- var msg = this.config.message;
-
- if (board.loadable) {
- return ['', ' ', msg.loading, ''].join('');
- }
- if (board.completed && board.issues.length > 0) {
- return ['', msg.allComplete, ''].join('');
- }
- return ['', msg.empty, ''].join('');
- }
- }]);
- return BoardRenderer;
- }(Renderer);
-
- var Board = function () {
- function Board(data, config) {
- var _this2 = this;
-
- classCallCheck(this, Board);
-
- this.page = 0;
- this.loadable = true;
- this.loading = false;
- this.completed = false;
- this.issues = [];
-
- this.name = data.name;
- this.icon = data.icon;
- this.state = data.state;
- this.color = data.color;
- this.colorTarget = data.colorTarget;
- this.issuesCount = data.issuesCount || 0;
- this.avatarUrl = data.avatarUrl;
-
- this.config = config;
-
- this.renderer = new BoardRenderer(config);
- this.cardRenderer = new CardRenderer(config);
-
- this.$tip = null;
- this.$el = $(this.renderer.render(this));
- this.$dimmer = this.$el.find('.ui.dimmer');
- this.$issues = this.$el.find('.board-list');
- this.$issuesCount = this.$el.find('.issues-count');
-
- this.$issues.on('scroll', function () {
- _this2.autoload();
- });
- }
-
- createClass(Board, [{
- key: 'add',
- value: function add(issue) {
- this.issues.push(issue);
- this.issuesCount += 1;
- this.$issuesCount.text(this.issuesCount);
- }
- }, {
- key: 'find',
- value: function find(id) {
- for (var i = 0; i < this.issues.length; ++i) {
- var issue = this.issues[i];
- if (issue.id === id) {
- return i;
- }
- }
- return -1;
- }
- }, {
- key: 'get',
- value: function get$$1(id) {
- var i = this.find(id);
-
- if (i >= 0) {
- return this.issues[i];
- }
- return null;
- }
- }, {
- key: 'remove',
- value: function remove(id) {
- var i = this.find(id);
-
- if (i >= 0) {
- this.issuesCount -= 1;
- this.$issuesCount.text(this.issuesCount);
- return this.issues.splice(i, 1);
- }
- return null;
- }
- }, {
- key: 'clear',
- value: function clear() {
- this.page = 0;
- this.issues = [];
- this.issuesCount = 0;
- this.loading = false;
- this.loadable = true;
- this.completed = false;
-
- this.$issuesCount.text(0);
- this.$issues.empty();
- this.$tip = null;
- }
- }, {
- key: 'autoload',
- value: function autoload() {
- if (this.completed) {
- return;
- }
- if (!this.$tip || this.$tip.position().top < this.$issues.height()) {
- this.load();
- }
- }
- }, {
- key: 'load',
- value: function load() {
- if (this.loading) {
- return false;
- }
- this.page += 1;
- this.loading = true;
- if (this.page === 1) {
- this.$dimmer.addClass('active');
- }
- this.config.onLoad(this, this.onLoadDone.bind(this));
- return true;
- }
- }, {
- key: 'onLoadDone',
- value: function onLoadDone(issues, count) {
- this.issuesCount = count;
- this.$issuesCount.text(this.issuesCount);
- this.appendIssues(issues);
- if (this.issuesCount > 0) {
- if (issues.length < 1 || this.issuesCount === issues.length) {
- this.loadable = false;
- this.completed = true;
- } else {
- this.loadable = true;
- this.completed = false;
- }
- } else {
- this.loadable = false;
- this.completed = true;
- }
- if (this.page === 1) {
- this.$dimmer.removeClass('active');
- }
- this.loading = false;
- this.updateTip();
- this.autoload();
- }
-
- /* 进行初次加载 */
-
- }, {
- key: 'firstload',
- value: function firstload() {
- if (this.page > 0) {
- return false;
- }
- return this.load();
- }
-
- /**
- * 更新提示
- */
-
- }, {
- key: 'updateTip',
- value: function updateTip() {
- if (this.$tip) {
- this.$tip.remove();
- }
- this.$tip = $(this.renderer.renderTip(this));
- this.$issues.append(this.$tip);
- }
- }, {
- key: 'createCard',
- value: function createCard(issue) {
- var $card = $(this.cardRenderer.render(issue));
- var onSelect = this.config.onSelect;
-
- if (onSelect) {
- $card.on('click', function (e) {
- var $target = $(e.target);
-
- if (!$target.is('a')) {
- $target = $target.parent();
- }
- if (!$target.parent().hasClass('card-header') && $target.is('a') && $target.attr('href')) {
- return;
- }
- onSelect(issue, e);
- });
- }
- return this.config.onRender(issue, $card, this.config);
- }
- }, {
- key: 'appendIssue',
- value: function appendIssue(issue) {
- this.issues.push(issue);
- this.$issues.append(this.createCard(issue));
- }
- }, {
- key: 'prependIssue',
- value: function prependIssue(issue) {
- this.issuesCount += 1;
- this.issues.splice(0, 0, issue);
- this.$issues.prepend(this.createCard(issue));
- this.$issuesCount.text(this.issuesCount);
- }
- }, {
- key: 'updateIssue',
- value: function updateIssue(issue) {
- var $issue = $('#' + this.config.name + '-issue-' + issue.id);
-
- if ($issue.length < 1) {
- this.prependIssue(issue);
- return;
- }
- $issue.before(this.createCard(issue)).remove();
- }
-
- /**
- * 直接追加多个任务,不更新任务总数
- * @param {Array} issues 任务列表
- */
-
- }, {
- key: 'appendIssues',
- value: function appendIssues(issues) {
- var _this3 = this;
-
- issues.filter(function (issue) {
- return _this3.issues.every(function (boardIssue) {
- return boardIssue.id !== issue.id;
- });
- }).forEach(function (issue) {
- issue[_this3.config.Key] = _this3.state;
- _this3.appendIssue(issue);
- });
- }
- }]);
- return Board;
- }();
-
- var Boards = function () {
- /**
- * 创建一个看板
- * @param {JQuery} $el 看板容器元素
- * @param {BoardsSettings} options 配置
- */
- function Boards($el, options) {
- classCallCheck(this, Boards);
-
- var config = new Config(options);
-
- this.$el = $el;
- this.config = config;
-
- this.boards = {};
- this.$hoverIssue = null;
- this.$selectedIssue = null;
- this.timerForScrollLoad = null;
-
- this.bindDrag();
- this.bindScroll();
- this.initPlugins();
- this.setData(config.data);
- }
-
- createClass(Boards, [{
- key: 'initPlugins',
- value: function initPlugins() {
- this.initSortable();
- }
-
- // 初始化拖拽排序功能
-
- }, {
- key: 'initSortable',
- value: function initSortable() {
- var that = this;
- var Sortable = that.config.plugins.Sortable;
-
- // 如果没有注入 SortableJS 依赖,则不启用这个功能
- if (!Sortable) {
- return false;
- }
- that.$el.addClass('boards-sortable');
- that.sortable = Sortable.create(that.$el[0], {
- handle: '.board-title',
- dataIdAttr: 'data-state',
- onUpdate: function onUpdate() {
- that.config.onSorted(that.sortable.toArray());
- }
- });
- that.$el.on('click', '.board-action', function (e) {
- var $target = $(this);
- var id = $target.data('id');
- var state = $target.parents('.board').data('state');
- var actions = that.config.actions;
-
- if (typeof actions === 'function') {
- actions = actions(that.config);
- }
- actions.some(function (action) {
- if (action.id === id && action.callback) {
- action.callback(that, that.boards[state], e);
- return true;
- }
- return false;
- });
- });
- return true;
- }
- }, {
- key: 'bindScroll',
- value: function bindScroll() {
- var that = this;
- var timerForScrollLoad = null;
-
- function onScrollLoad() {
- if (timerForScrollLoad) {
- clearTimeout(timerForScrollLoad);
- }
- timerForScrollLoad = setTimeout(function () {
- timerForScrollLoad = null;
- that.load();
- }, 200);
- }
-
- $(window).on('resize', onScrollLoad);
- this.$el.on('scroll', onScrollLoad);
- }
- }, {
- key: 'bindDrag',
- value: function bindDrag() {
- var that = this;
-
- if (that.config.readonly) {
- return;
- }
- that.$el.on('dragstart', '.card', function (e) {
- var issueId = $(this).data('id');
- var issue = that.getIssue(issueId);
-
- if (issue) {
- that.setFocus(issue.type, issue.state);
- }
- that.$selectedIssue = $(this);
- e.originalEvent.dataTransfer.setData('text/plain', issueId);
- e.stopPropagation();
- });
- that.$el.on('dragend', '.card', function () {
- that.clearFocus();
- });
- that.$el.on('drop', '.board-list', function (e) {
- e.preventDefault();
- e.stopPropagation();
-
- if (that.$hoverIssue) {
- that.$hoverIssue.removeClass('card-dragover');
- }
- if (!that.$selectedIssue) {
- return false;
- }
- if (that.config.readonly) {
- return false;
- }
-
- var $issue = that.$selectedIssue;
- var issueId = $issue.data('id');
- var $board = $(this).parents('.board');
- var state = $board.data('state');
- var oldState = $issue.parents('.board').data('state');
- var nextIssueId = that.$hoverIssue ? that.$hoverIssue.data('id') : null;
-
- that.setIssueState(issueId, state, nextIssueId, function (issue) {
- that.config.onUpdate(issue, oldState, nextIssueId);
- });
- return true;
- });
- that.$el.on('dragover', '.board-list', function (e) {
- var key = that.config.key;
- var $target = $(e.target);
-
- if (!that.$selectedIssue) {
- return;
- }
-
- e.preventDefault();
- while ($target.length > 0 && !$target.hasClass('card')) {
- $target = $target.parent();
- }
- if ($target.length < 1) {
- if (that.$hoverIssue) {
- that.$hoverIssue.removeClass('card-dragover');
- }
- that.$hoverIssue = null;
- return;
- }
- if (that.$hoverIssue) {
- that.$hoverIssue.removeClass('card-dragover');
- }
- that.$hoverIssue = $target;
- var hoverIssue = that.getIssue($target.data('id'));
- var selectedIssue = that.getIssue(that.$selectedIssue.data('id'));
- if (hoverIssue && selectedIssue && hoverIssue[key] !== selectedIssue[key]) {
- that.$hoverIssue.addClass('card-dragover');
- }
- });
- }
-
- /**
- * 设置焦点板块
- * 根据指定的类型和状态,排除无关状态的板块
- * @param {String, Number} typeId 任务类型 id
- * @param {String, Number} stateId 任务状态 id
- */
-
- }, {
- key: 'setFocus',
- value: function setFocus(typeId, stateId) {
- var _this = this;
-
- var stateIds = [];
- var issueType = null;
-
- if (this.config.key !== 'state') {
- return;
- }
- this.config.types.some(function (t) {
- if (t.id === typeId) {
- issueType = t;
- return true;
- }
- return false;
- });
- if (issueType) {
- stateIds = issueType.states.map(function (state) {
- return state.id.toString();
- });
- }
- Object.keys(this.boards).forEach(function (id) {
- if (id !== stateId.toString() && stateIds.indexOf(id) === -1) {
- _this.boards[id].$el.addClass('board-blur');
- }
- });
- }
-
- /* 清除板块的焦点效果 */
-
- }, {
- key: 'clearFocus',
- value: function clearFocus() {
- var _this2 = this;
-
- Object.keys(this.boards).forEach(function (key) {
- _this2.boards[key].$el.removeClass('board-blur');
- });
- }
- }, {
- key: 'getIssueCard',
- value: function getIssueCard(id) {
- return $('#' + this.config.name + '-issue-' + id);
- }
- }, {
- key: 'getIssue',
- value: function getIssue(id) {
- var $issue = this.getIssueCard(id);
- var $board = $issue.parents('.board');
- var state = $board.data('state');
- var board$$1 = this.boards[state];
- if (board$$1) {
- return board$$1.get(id);
- }
- return null;
- }
- }, {
- key: 'removeIssue',
- value: function removeIssue(id) {
- var issue = null;
- var $issue = this.getIssueCard(id);
-
- if ($issue.length < 1) {
- return issue;
- }
-
- var state = $issue.parents('.board').data('state');
- if (state) {
- var board$$1 = this.boards[state];
- if (board$$1) {
- issue = board$$1.remove(id);
- }
- }
-
- $issue.remove();
- return issue;
- }
- }, {
- key: 'updateIssue',
- value: function updateIssue(issue) {
- var board$$1 = this.boards[issue[this.config.key]];
-
- if (board$$1) {
- board$$1.updateIssue(issue);
- return true;
- }
- return false;
- }
- }, {
- key: 'prependIssue',
- value: function prependIssue(issue) {
- var board$$1 = this.boards[issue[this.config.key]];
-
- if (board$$1) {
- board$$1.prependIssue(issue);
- return true;
- }
- return false;
- }
- }, {
- key: 'setIssueState',
- value: function setIssueState(issueId, state, nextIssueId, callback) {
- var $issue = this.getIssueCard(issueId);
- var $nextIssue = nextIssueId ? this.getIssueCard(nextIssueId) : null;
-
- if ($issue.length < 1) {
- return null;
- }
-
- var user = this.config.user;
- var $oldBoard = $issue.parents('.board');
- var oldState = $oldBoard.data('state');
- var oldBoard = this.boards[oldState];
- var newBoard = this.boards[state];
-
- if (oldBoard.state === state) {
- return null;
- }
-
- // 如果新的板块不接受该状态的 issue
- if (newBoard.exclude && newBoard.exclude.indexOf(oldState) >= 0) {
- return null;
- }
-
- var issue = oldBoard.get(issueId);
- // 如果当前用户既不具备管理权限,也不是 issue 作者,则禁止操作
- if (!user.admin && issue.author.id !== user.id) {
- return null;
- }
-
- issue[this.config.key] = state;
- newBoard.add(issue);
- oldBoard.remove(issue.id);
- $issue.hide(256, function () {
- // 如果有指定下一个 issue,则将当前 issue 插入到它前面
- if ($nextIssue) {
- $nextIssue.before($issue);
- } else {
- newBoard.$issues.prepend($issue);
- }
- $issue.show(256, function () {
- if (callback) {
- callback(issue);
- }
- });
- });
- newBoard.updateTip();
- oldBoard.updateTip();
- oldBoard.autoload();
-
- return issue;
- }
- }, {
- key: 'load',
- value: function load() {
- var _this3 = this;
-
- var count = 0;
- var bound = this.$el.offset();
-
- // 设置边界框(可见区域)的尺寸
- bound.width = this.$el.width();
- bound.height = this.$el.height();
-
- Object.keys(this.boards).forEach(function (state) {
- var board$$1 = _this3.boards[state];
- var offset = board$$1.$el.offset();
- // 如果当前板块在可见区域内
- if (offset.top + board$$1.$el.height() > bound.top && offset.left + board$$1.$el.width() > bound.left && offset.top < bound.top + bound.height && offset.left < bound.left + bound.width) {
- if (board$$1.firstload()) {
- count += 1;
- }
- }
- });
- return count;
- }
- }, {
- key: 'setData',
- value: function setData(data) {
- var _this4 = this;
-
- this.boards = {};
- this.$el.addClass('boards-list').empty();
-
- data.forEach(function (boardData) {
- var board$$1 = new Board(boardData, _this4.config);
- _this4.boards[boardData.state] = board$$1;
- _this4.$el.append(board$$1.$el);
- });
- }
- }, {
- key: 'clearData',
- value: function clearData() {
- var _this5 = this;
-
- Object.keys(this.boards).forEach(function (state) {
- _this5.boards[state].clear();
- });
- }
- }]);
- return Boards;
- }();
-
- $.fn.boards = function (options) {
- var that = this.data('boards');
- var settings = $.extend({}, $.fn.boards.settings, options);
-
- if (!that) {
- that = new Boards(this, settings);
- this.data('boards', that);
- that.load();
- }
- return this;
- };
-
- $.fn.boards.settings = defaults$1;
+ 'use strict';
+
+ function unwrapExports (x) {
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+ }
+
+ function createCommonjsModule(fn, module) {
+ return module = { exports: {} }, fn(module, module.exports), module.exports;
+ }
+
+ var classCallCheck = createCommonjsModule(function (module) {
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+
+ module.exports = _classCallCheck;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ var _classCallCheck = unwrapExports(classCallCheck);
+
+ var createClass = createCommonjsModule(function (module) {
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+
+ module.exports = _createClass;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ var _createClass = unwrapExports(createClass);
+
+ var runtime_1 = createCommonjsModule(function (module) {
+ /**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+ var runtime = function (exports) {
+
+ var Op = Object.prototype;
+ var hasOwn = Op.hasOwnProperty;
+ var undefined$1; // More compressible than void 0.
+
+ var $Symbol = typeof Symbol === "function" ? Symbol : {};
+ var iteratorSymbol = $Symbol.iterator || "@@iterator";
+ var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
+ var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+
+ function define(obj, key, value) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ return obj[key];
+ }
+
+ try {
+ // IE 8 has a broken Object.defineProperty that only works on DOM objects.
+ define({}, "");
+ } catch (err) {
+ define = function (obj, key, value) {
+ return obj[key] = value;
+ };
+ }
+
+ function wrap(innerFn, outerFn, self, tryLocsList) {
+ // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
+ var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
+ var generator = Object.create(protoGenerator.prototype);
+ var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
+ // .throw, and .return methods.
+
+ generator._invoke = makeInvokeMethod(innerFn, self, context);
+ return generator;
+ }
+
+ exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
+ // record like context.tryEntries[i].completion. This interface could
+ // have been (and was previously) designed to take a closure to be
+ // invoked without arguments, but in all the cases we care about we
+ // already have an existing method we want to call, so there's no need
+ // to create a new function object. We can even get away with assuming
+ // the method takes exactly one argument, since that happens to be true
+ // in every case, so we don't have to touch the arguments object. The
+ // only additional allocation required is the completion record, which
+ // has a stable shape and so hopefully should be cheap to allocate.
+
+ function tryCatch(fn, obj, arg) {
+ try {
+ return {
+ type: "normal",
+ arg: fn.call(obj, arg)
+ };
+ } catch (err) {
+ return {
+ type: "throw",
+ arg: err
+ };
+ }
+ }
+
+ var GenStateSuspendedStart = "suspendedStart";
+ var GenStateSuspendedYield = "suspendedYield";
+ var GenStateExecuting = "executing";
+ var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
+ // breaking out of the dispatch switch statement.
+
+ var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
+ // .constructor.prototype properties for functions that return Generator
+ // objects. For full spec compliance, you may wish to configure your
+ // minifier not to mangle the names of these two functions.
+
+ function Generator() {}
+
+ function GeneratorFunction() {}
+
+ function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
+ // don't natively support it.
+
+
+ var IteratorPrototype = {};
+
+ IteratorPrototype[iteratorSymbol] = function () {
+ return this;
+ };
+
+ var getProto = Object.getPrototypeOf;
+ var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+
+ if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
+ // This environment has a native %IteratorPrototype%; use it instead
+ // of the polyfill.
+ IteratorPrototype = NativeIteratorPrototype;
+ }
+
+ var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
+ GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
+ GeneratorFunctionPrototype.constructor = GeneratorFunction;
+ GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the
+ // Iterator interface in terms of a single ._invoke method.
+
+ function defineIteratorMethods(prototype) {
+ ["next", "throw", "return"].forEach(function (method) {
+ define(prototype, method, function (arg) {
+ return this._invoke(method, arg);
+ });
+ });
+ }
+
+ exports.isGeneratorFunction = function (genFun) {
+ var ctor = typeof genFun === "function" && genFun.constructor;
+ return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
+ // do is to check its .name property.
+ (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
+ };
+
+ exports.mark = function (genFun) {
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
+ } else {
+ genFun.__proto__ = GeneratorFunctionPrototype;
+ define(genFun, toStringTagSymbol, "GeneratorFunction");
+ }
+
+ genFun.prototype = Object.create(Gp);
+ return genFun;
+ }; // Within the body of any async function, `await x` is transformed to
+ // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
+ // `hasOwn.call(value, "__await")` to determine if the yielded value is
+ // meant to be awaited.
+
+
+ exports.awrap = function (arg) {
+ return {
+ __await: arg
+ };
+ };
+
+ function AsyncIterator(generator, PromiseImpl) {
+ function invoke(method, arg, resolve, reject) {
+ var record = tryCatch(generator[method], generator, arg);
+
+ if (record.type === "throw") {
+ reject(record.arg);
+ } else {
+ var result = record.arg;
+ var value = result.value;
+
+ if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
+ return PromiseImpl.resolve(value.__await).then(function (value) {
+ invoke("next", value, resolve, reject);
+ }, function (err) {
+ invoke("throw", err, resolve, reject);
+ });
+ }
+
+ return PromiseImpl.resolve(value).then(function (unwrapped) {
+ // When a yielded Promise is resolved, its final value becomes
+ // the .value of the Promise<{value,done}> result for the
+ // current iteration.
+ result.value = unwrapped;
+ resolve(result);
+ }, function (error) {
+ // If a rejected Promise was yielded, throw the rejection back
+ // into the async generator function so it can be handled there.
+ return invoke("throw", error, resolve, reject);
+ });
+ }
+ }
+
+ var previousPromise;
+
+ function enqueue(method, arg) {
+ function callInvokeWithMethodAndArg() {
+ return new PromiseImpl(function (resolve, reject) {
+ invoke(method, arg, resolve, reject);
+ });
+ }
+
+ return previousPromise = // If enqueue has been called before, then we want to wait until
+ // all previous Promises have been resolved before calling invoke,
+ // so that results are always delivered in the correct order. If
+ // enqueue has not been called before, then it is important to
+ // call invoke immediately, without waiting on a callback to fire,
+ // so that the async generator function has the opportunity to do
+ // any necessary setup in a predictable way. This predictability
+ // is why the Promise constructor synchronously invokes its
+ // executor callback, and why async functions synchronously
+ // execute code before the first await. Since we implement simple
+ // async functions in terms of async generators, it is especially
+ // important to get this right, even though it requires care.
+ previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
+ // invocations of the iterator.
+ callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
+ } // Define the unified helper method that is used to implement .next,
+ // .throw, and .return (see defineIteratorMethods).
+
+
+ this._invoke = enqueue;
+ }
+
+ defineIteratorMethods(AsyncIterator.prototype);
+
+ AsyncIterator.prototype[asyncIteratorSymbol] = function () {
+ return this;
+ };
+
+ exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
+ // AsyncIterator objects; they just return a Promise for the value of
+ // the final result produced by the iterator.
+
+ exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
+ if (PromiseImpl === void 0) PromiseImpl = Promise;
+ var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
+ return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
+ : iter.next().then(function (result) {
+ return result.done ? result.value : iter.next();
+ });
+ };
+
+ function makeInvokeMethod(innerFn, self, context) {
+ var state = GenStateSuspendedStart;
+ return function invoke(method, arg) {
+ if (state === GenStateExecuting) {
+ throw new Error("Generator is already running");
+ }
+
+ if (state === GenStateCompleted) {
+ if (method === "throw") {
+ throw arg;
+ } // Be forgiving, per 25.3.3.3.3 of the spec:
+ // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
+
+
+ return doneResult();
+ }
+
+ context.method = method;
+ context.arg = arg;
+
+ while (true) {
+ var delegate = context.delegate;
+
+ if (delegate) {
+ var delegateResult = maybeInvokeDelegate(delegate, context);
+
+ if (delegateResult) {
+ if (delegateResult === ContinueSentinel) continue;
+ return delegateResult;
+ }
+ }
+
+ if (context.method === "next") {
+ // Setting context._sent for legacy support of Babel's
+ // function.sent implementation.
+ context.sent = context._sent = context.arg;
+ } else if (context.method === "throw") {
+ if (state === GenStateSuspendedStart) {
+ state = GenStateCompleted;
+ throw context.arg;
+ }
+
+ context.dispatchException(context.arg);
+ } else if (context.method === "return") {
+ context.abrupt("return", context.arg);
+ }
+
+ state = GenStateExecuting;
+ var record = tryCatch(innerFn, self, context);
+
+ if (record.type === "normal") {
+ // If an exception is thrown from innerFn, we leave state ===
+ // GenStateExecuting and loop back for another invocation.
+ state = context.done ? GenStateCompleted : GenStateSuspendedYield;
+
+ if (record.arg === ContinueSentinel) {
+ continue;
+ }
+
+ return {
+ value: record.arg,
+ done: context.done
+ };
+ } else if (record.type === "throw") {
+ state = GenStateCompleted; // Dispatch the exception by looping back around to the
+ // context.dispatchException(context.arg) call above.
+
+ context.method = "throw";
+ context.arg = record.arg;
+ }
+ }
+ };
+ } // Call delegate.iterator[context.method](context.arg) and handle the
+ // result, either by returning a { value, done } result from the
+ // delegate iterator, or by modifying context.method and context.arg,
+ // setting context.delegate to null, and returning the ContinueSentinel.
+
+
+ function maybeInvokeDelegate(delegate, context) {
+ var method = delegate.iterator[context.method];
+
+ if (method === undefined$1) {
+ // A .throw or .return when the delegate iterator has no .throw
+ // method always terminates the yield* loop.
+ context.delegate = null;
+
+ if (context.method === "throw") {
+ // Note: ["return"] must be used for ES3 parsing compatibility.
+ if (delegate.iterator["return"]) {
+ // If the delegate iterator has a return method, give it a
+ // chance to clean up.
+ context.method = "return";
+ context.arg = undefined$1;
+ maybeInvokeDelegate(delegate, context);
+
+ if (context.method === "throw") {
+ // If maybeInvokeDelegate(context) changed context.method from
+ // "return" to "throw", let that override the TypeError below.
+ return ContinueSentinel;
+ }
+ }
+
+ context.method = "throw";
+ context.arg = new TypeError("The iterator does not provide a 'throw' method");
+ }
+
+ return ContinueSentinel;
+ }
+
+ var record = tryCatch(method, delegate.iterator, context.arg);
+
+ if (record.type === "throw") {
+ context.method = "throw";
+ context.arg = record.arg;
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ var info = record.arg;
+
+ if (!info) {
+ context.method = "throw";
+ context.arg = new TypeError("iterator result is not an object");
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ if (info.done) {
+ // Assign the result of the finished delegate to the temporary
+ // variable specified by delegate.resultName (see delegateYield).
+ context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
+
+ context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
+ // exception, let the outer generator proceed normally. If
+ // context.method was "next", forget context.arg since it has been
+ // "consumed" by the delegate iterator. If context.method was
+ // "return", allow the original .return call to continue in the
+ // outer generator.
+
+ if (context.method !== "return") {
+ context.method = "next";
+ context.arg = undefined$1;
+ }
+ } else {
+ // Re-yield the result returned by the delegate method.
+ return info;
+ } // The delegate iterator is finished, so forget it and continue with
+ // the outer generator.
+
+
+ context.delegate = null;
+ return ContinueSentinel;
+ } // Define Generator.prototype.{next,throw,return} in terms of the
+ // unified ._invoke helper method.
+
+
+ defineIteratorMethods(Gp);
+ define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the
+ // @@iterator function is called on it. Some browsers' implementations of the
+ // iterator prototype chain incorrectly implement this, causing the Generator
+ // object to not be returned from this call. This ensures that doesn't happen.
+ // See https://github.com/facebook/regenerator/issues/274 for more details.
+
+ Gp[iteratorSymbol] = function () {
+ return this;
+ };
+
+ Gp.toString = function () {
+ return "[object Generator]";
+ };
+
+ function pushTryEntry(locs) {
+ var entry = {
+ tryLoc: locs[0]
+ };
+
+ if (1 in locs) {
+ entry.catchLoc = locs[1];
+ }
+
+ if (2 in locs) {
+ entry.finallyLoc = locs[2];
+ entry.afterLoc = locs[3];
+ }
+
+ this.tryEntries.push(entry);
+ }
+
+ function resetTryEntry(entry) {
+ var record = entry.completion || {};
+ record.type = "normal";
+ delete record.arg;
+ entry.completion = record;
+ }
+
+ function Context(tryLocsList) {
+ // The root entry object (effectively a try statement without a catch
+ // or a finally block) gives us a place to store values thrown from
+ // locations where there is no enclosing try statement.
+ this.tryEntries = [{
+ tryLoc: "root"
+ }];
+ tryLocsList.forEach(pushTryEntry, this);
+ this.reset(true);
+ }
+
+ exports.keys = function (object) {
+ var keys = [];
+
+ for (var key in object) {
+ keys.push(key);
+ }
+
+ keys.reverse(); // Rather than returning an object with a next method, we keep
+ // things simple and return the next function itself.
+
+ return function next() {
+ while (keys.length) {
+ var key = keys.pop();
+
+ if (key in object) {
+ next.value = key;
+ next.done = false;
+ return next;
+ }
+ } // To avoid creating an additional object, we just hang the .value
+ // and .done properties off the next function object itself. This
+ // also ensures that the minifier will not anonymize the function.
+
+
+ next.done = true;
+ return next;
+ };
+ };
+
+ function values(iterable) {
+ if (iterable) {
+ var iteratorMethod = iterable[iteratorSymbol];
+
+ if (iteratorMethod) {
+ return iteratorMethod.call(iterable);
+ }
+
+ if (typeof iterable.next === "function") {
+ return iterable;
+ }
+
+ if (!isNaN(iterable.length)) {
+ var i = -1,
+ next = function next() {
+ while (++i < iterable.length) {
+ if (hasOwn.call(iterable, i)) {
+ next.value = iterable[i];
+ next.done = false;
+ return next;
+ }
+ }
+
+ next.value = undefined$1;
+ next.done = true;
+ return next;
+ };
+
+ return next.next = next;
+ }
+ } // Return an iterator with no values.
+
+
+ return {
+ next: doneResult
+ };
+ }
+
+ exports.values = values;
+
+ function doneResult() {
+ return {
+ value: undefined$1,
+ done: true
+ };
+ }
+
+ Context.prototype = {
+ constructor: Context,
+ reset: function (skipTempReset) {
+ this.prev = 0;
+ this.next = 0; // Resetting context._sent for legacy support of Babel's
+ // function.sent implementation.
+
+ this.sent = this._sent = undefined$1;
+ this.done = false;
+ this.delegate = null;
+ this.method = "next";
+ this.arg = undefined$1;
+ this.tryEntries.forEach(resetTryEntry);
+
+ if (!skipTempReset) {
+ for (var name in this) {
+ // Not sure about the optimal order of these conditions:
+ if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
+ this[name] = undefined$1;
+ }
+ }
+ }
+ },
+ stop: function () {
+ this.done = true;
+ var rootEntry = this.tryEntries[0];
+ var rootRecord = rootEntry.completion;
+
+ if (rootRecord.type === "throw") {
+ throw rootRecord.arg;
+ }
+
+ return this.rval;
+ },
+ dispatchException: function (exception) {
+ if (this.done) {
+ throw exception;
+ }
+
+ var context = this;
+
+ function handle(loc, caught) {
+ record.type = "throw";
+ record.arg = exception;
+ context.next = loc;
+
+ if (caught) {
+ // If the dispatched exception was caught by a catch block,
+ // then let that catch block handle the exception normally.
+ context.method = "next";
+ context.arg = undefined$1;
+ }
+
+ return !!caught;
+ }
+
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ var record = entry.completion;
+
+ if (entry.tryLoc === "root") {
+ // Exception thrown outside of any try block that could handle
+ // it, so set the completion value of the entire function to
+ // throw the exception.
+ return handle("end");
+ }
+
+ if (entry.tryLoc <= this.prev) {
+ var hasCatch = hasOwn.call(entry, "catchLoc");
+ var hasFinally = hasOwn.call(entry, "finallyLoc");
+
+ if (hasCatch && hasFinally) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ } else if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+ } else if (hasCatch) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ }
+ } else if (hasFinally) {
+ if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+ } else {
+ throw new Error("try statement without catch or finally");
+ }
+ }
+ }
+ },
+ abrupt: function (type, arg) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
+ var finallyEntry = entry;
+ break;
+ }
+ }
+
+ if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
+ // Ignore the finally entry if control is not jumping to a
+ // location outside the try/catch block.
+ finallyEntry = null;
+ }
+
+ var record = finallyEntry ? finallyEntry.completion : {};
+ record.type = type;
+ record.arg = arg;
+
+ if (finallyEntry) {
+ this.method = "next";
+ this.next = finallyEntry.finallyLoc;
+ return ContinueSentinel;
+ }
+
+ return this.complete(record);
+ },
+ complete: function (record, afterLoc) {
+ if (record.type === "throw") {
+ throw record.arg;
+ }
+
+ if (record.type === "break" || record.type === "continue") {
+ this.next = record.arg;
+ } else if (record.type === "return") {
+ this.rval = this.arg = record.arg;
+ this.method = "return";
+ this.next = "end";
+ } else if (record.type === "normal" && afterLoc) {
+ this.next = afterLoc;
+ }
+
+ return ContinueSentinel;
+ },
+ finish: function (finallyLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.finallyLoc === finallyLoc) {
+ this.complete(entry.completion, entry.afterLoc);
+ resetTryEntry(entry);
+ return ContinueSentinel;
+ }
+ }
+ },
+ "catch": function (tryLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.tryLoc === tryLoc) {
+ var record = entry.completion;
+
+ if (record.type === "throw") {
+ var thrown = record.arg;
+ resetTryEntry(entry);
+ }
+
+ return thrown;
+ }
+ } // The context.catch method must only be called with a location
+ // argument that corresponds to a known catch block.
+
+
+ throw new Error("illegal catch attempt");
+ },
+ delegateYield: function (iterable, resultName, nextLoc) {
+ this.delegate = {
+ iterator: values(iterable),
+ resultName: resultName,
+ nextLoc: nextLoc
+ };
+
+ if (this.method === "next") {
+ // Deliberately forget the last sent value so that we don't
+ // accidentally pass it on to the delegate.
+ this.arg = undefined$1;
+ }
+
+ return ContinueSentinel;
+ }
+ }; // Regardless of whether this script is executing as a CommonJS module
+ // or not, return the runtime object so that we can declare the variable
+ // regeneratorRuntime in the outer scope, which allows this module to be
+ // injected easily by `bin/regenerator --include-runtime script.js`.
+
+ return exports;
+ }( // If this script is executing as a CommonJS module, use module.exports
+ // as the regeneratorRuntime namespace. Otherwise create a new empty
+ // object. Either way, the resulting object will be used to initialize
+ // the regeneratorRuntime variable at the top of this file.
+ module.exports );
+
+ try {
+ regeneratorRuntime = runtime;
+ } catch (accidentalStrictMode) {
+ // This module should not be running in strict mode, so the above
+ // assignment should always work unless something is misconfigured. Just
+ // in case runtime.js accidentally runs in strict mode, we can escape
+ // strict mode using a global Function call. This could conceivably fail
+ // if a Content Security Policy forbids using Function, but in that case
+ // the proper solution is to fix the accidental strict mode problem. If
+ // you've misconfigured your bundler to force strict mode and applied a
+ // CSP to forbid Function, and you're not willing to fix either of those
+ // problems, please detail your unique predicament in a GitHub issue.
+ Function("r", "regeneratorRuntime = r")(runtime);
+ }
+ });
+
+ var regenerator = runtime_1;
+
+ var htmlSafe = function () {
+ var $el = $('');
+ return function (text) {
+ return $el.text(text).html();
+ };
+ }();
+
+ var defaults = {
+ readonly: false,
+ key: 'state',
+ name: 'board',
+ message: {
+ loading: 'loading ...',
+ stateDisabled: 'Current issue cannot switch to this state',
+ allComplete: 'Showing all issues',
+ empty: 'There are no issues here',
+ btnSetFirst: 'Move it to the first',
+ btnSetLast: 'Move it to the last'
+ },
+ className: {
+ iconComment: 'icon comments outline',
+ iconAngleLeft: 'icon angle double left',
+ iconAngleRight: 'icon angle double right',
+ iconIssue: 'icon sticky note outline',
+ card: 'ui link card',
+ action: 'ui button',
+ actions: 'ui mini basic icon buttons',
+ avatar: 'ui avatar image'
+ },
+ labelsTemplate: function labelsTemplate(label) {
+ return " \n ").concat(htmlSafe(label.name), "\n ");
+ },
+ actions: function actions(config) {
+ if (!config.plugins.Sortable) {
+ return [];
+ }
+
+ return [{
+ id: 'btn-set-first',
+ "class": config.className.action,
+ icon: config.className.iconAngleLeft,
+ title: config.message.btnSetFirst,
+ callback: function callback(boards, board) {
+ var state = board.state.toString();
+ var states = boards.sortable.toArray();
+ var i = states.indexOf(state);
+
+ if (i >= 0) {
+ states.splice(i, 1);
+ states.splice(0, 0, state);
+ boards.sortable.sort(states);
+ config.onSorted(states);
+ boards.load();
+ }
+ }
+ }, {
+ id: 'btn-set-last',
+ "class": config.className.action,
+ icon: config.className.iconAngleRight,
+ title: config.message.btnSetLast,
+ callback: function callback(boards, board) {
+ var state = board.state.toString();
+ var states = boards.sortable.toArray();
+ var i = states.indexOf(state);
+
+ if (i >= 0) {
+ states.splice(i, 1);
+ states.push(state);
+ boards.sortable.sort(states);
+ config.onSorted(states);
+ boards.load();
+ }
+ }
+ }];
+ },
+ data: [{
+ order: 1,
+ name: 'Backlog',
+ state: 'open',
+ color: '#ffa726',
+ issuesCount: 0
+ }, {
+ order: 2,
+ name: 'Done',
+ state: 'closed',
+ color: '#2baf2b',
+ issuesCount: 0
+ }],
+ plugins: {},
+ types: [],
+ user: {
+ id: 0,
+ admin: false
+ },
+
+ /**
+ * 在任务列表加载完后的回调
+ * @callback BoardLoadCallback
+ * @param {Array} issues 任务列表
+ * @param {Number} count 任务总数
+ */
+
+ /**
+ * 在开始加载任务列表时的回调
+ * @param {Object,Board} board 板块对象
+ * @param {BoardLoadCallback} callback 用于接收任务列表的回调函数
+ */
+ onLoad: function onLoad(board, callback) {
+ $.ajax({
+ url: 'issues',
+ data: {
+ state: board.state,
+ page: board.page
+ }
+ }).done(function () {
+ callback([], 0);
+ }).fail(function () {
+ callback([], 0);
+ });
+ },
+
+ /**
+ * 在更新任务时的回调
+ * @param {Object} issue 任务
+ * @param {String,Number} oldState 更新前的状态
+ */
+ onUpdate: function onUpdate(issue, oldState) {
+ var _this = this;
+
+ $.ajax({
+ type: 'PUT',
+ url: issue.url,
+ data: {
+ state: issue.state
+ }
+ }).done(function (res) {
+ _this.updateIssue(res);
+ }).fail(function () {
+ _this.setIssueState(issue.id, oldState);
+ });
+ },
+
+ /**
+ * 在渲染任务卡片时的回调
+ * @param {Object} issue 任务
+ * @param {JQuery} $el 任务卡片
+ */
+ onRender: function onRender(issue, $el) {
+ $el.addClass("issue-state-".concat(issue.state));
+ return $el;
+ },
+
+ /**
+ * 在板块被排序后的回调
+ * @param {Array} states 状态列表
+ */
+ onSorted: function onSorted(states) {
+ window.console.log(states);
+ }
+ };
+ var Config = function Config(config) {
+ _classCallCheck(this, Config);
+
+ $.extend(this, defaults, config);
+
+ if (config.className) {
+ this.className = $.extend({}, defaults.className, config.className);
+ }
+
+ if (config.message) {
+ this.message = $.extend({}, defaults.message, config.message);
+ }
+ };
+
+ var _typeof_1 = createCommonjsModule(function (module) {
+ function _typeof(obj) {
+ "@babel/helpers - typeof";
+
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+ module.exports = _typeof = function _typeof(obj) {
+ return typeof obj;
+ };
+
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ } else {
+ module.exports = _typeof = function _typeof(obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ };
+
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ }
+
+ return _typeof(obj);
+ }
+
+ module.exports = _typeof;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+
+ unwrapExports(_typeof_1);
+
+ var assertThisInitialized = createCommonjsModule(function (module) {
+ function _assertThisInitialized(self) {
+ if (self === void 0) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+
+ return self;
+ }
+
+ module.exports = _assertThisInitialized;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ unwrapExports(assertThisInitialized);
+
+ var possibleConstructorReturn = createCommonjsModule(function (module) {
+ var _typeof = _typeof_1["default"];
+
+ function _possibleConstructorReturn(self, call) {
+ if (call && (_typeof(call) === "object" || typeof call === "function")) {
+ return call;
+ }
+
+ return assertThisInitialized(self);
+ }
+
+ module.exports = _possibleConstructorReturn;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ var _possibleConstructorReturn = unwrapExports(possibleConstructorReturn);
+
+ var getPrototypeOf = createCommonjsModule(function (module) {
+ function _getPrototypeOf(o) {
+ module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
+ return o.__proto__ || Object.getPrototypeOf(o);
+ };
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ return _getPrototypeOf(o);
+ }
+
+ module.exports = _getPrototypeOf;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ var _getPrototypeOf = unwrapExports(getPrototypeOf);
+
+ var setPrototypeOf = createCommonjsModule(function (module) {
+ function _setPrototypeOf(o, p) {
+ module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
+ o.__proto__ = p;
+ return o;
+ };
+
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ return _setPrototypeOf(o, p);
+ }
+
+ module.exports = _setPrototypeOf;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ unwrapExports(setPrototypeOf);
+
+ var inherits = createCommonjsModule(function (module) {
+ function _inherits(subClass, superClass) {
+ if (typeof superClass !== "function" && superClass !== null) {
+ throw new TypeError("Super expression must either be null or a function");
+ }
+
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ writable: true,
+ configurable: true
+ }
+ });
+ if (superClass) setPrototypeOf(subClass, superClass);
+ }
+
+ module.exports = _inherits;
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
+ });
+ var _inherits = unwrapExports(inherits);
+
+ var Renderer =
+ /*#__PURE__*/
+ function () {
+ function Renderer(config) {
+ _classCallCheck(this, Renderer);
+
+ this.config = config;
+ }
+
+ _createClass(Renderer, [{
+ key: "getAvatarUrl",
+ value: function getAvatarUrl(name, avatarUrl) {
+ var Avatar = this.config.plugins.LetterAvatar;
+
+ if (!avatarUrl || avatarUrl.indexOf('no_portrait.png') === 0) {
+ if (Avatar) {
+ return Avatar(name);
+ }
+ }
+
+ return avatarUrl;
+ }
+ }, {
+ key: "getCardId",
+ value: function getCardId(issue) {
+ if (this.config.getIusseId) {
+ return this.config.getIusseId(issue);
+ }
+
+ return 'issue-card-' + issue.id;
+ }
+ }]);
+
+ return Renderer;
+ }();
+
+ /* eslint-disable indent */
+
+ function getUserUrl(user) {
+ return user.html_url || user.path;
+ }
+
+ function renderCardUserLabel(issue) {
+ if (!issue.author) {
+ return '';
+ }
+
+ if (typeof issue.author.is_member !== 'undefined') {
+ if (!issue.author.is_member) {
+ return '[访客]';
+ }
+ }
+
+ if (issue.author.outsourced) {
+ return '[外包]';
+ }
+
+ return '';
+ }
+
+ function renderCardLabels(issue, labelsTemplate) {
+ if (!issue.labels || !labelsTemplate) {
+ return '';
+ }
+
+ var html = issue.labels.map(labelsTemplate).join('');
+ return "".concat(html, "
");
+ }
+
+ var CardRenderer =
+ /*#__PURE__*/
+ function (_Renderer) {
+ _inherits(CardRenderer, _Renderer);
+
+ function CardRenderer() {
+ _classCallCheck(this, CardRenderer);
+
+ return _possibleConstructorReturn(this, _getPrototypeOf(CardRenderer).apply(this, arguments));
+ }
+
+ _createClass(CardRenderer, [{
+ key: "render",
+ value: function render(issue) {
+ var user = this.config.user;
+ var readonly = this.config.readonly;
+ var draggable = '';
+ var cardClass = this.config.className.card;
+
+ if (!readonly && (user.admin || user.id === issue.author.id)) {
+ draggable = 'draggable="true"';
+ cardClass += ' card-draggable';
+ }
+
+ return "\n \n
\n ").concat(htmlSafe(issue.title), "\n \n ").concat(this.config.topLevelLabel && this.config.topLevelLabel(issue) || '', "\n ").concat(this.config.priorityLabel && this.config.priorityLabel(issue) || '', "\n
\n \n ");
+ }
+ }, {
+ key: "renderState",
+ value: function renderState(issue) {
+ var state = issue.state_data;
+
+ if (!state || this.config.key === 'state') {
+ return '';
+ }
+
+ return "\n \n
");
+ }
+ }, {
+ key: "renderAssignee",
+ value: function renderAssignee(issue) {
+ var user = issue.assignee;
+
+ if (!user || !user.id || this.config.key !== 'state') {
+ return '';
+ }
+
+ return "");
+ }
+ }, {
+ key: "renderComments",
+ value: function renderComments(issue) {
+ var className = this.config.className.iconComment;
+
+ if (!issue.comments) {
+ return '';
+ }
+
+ return "");
+ }
+ }]);
+
+ return CardRenderer;
+ }(Renderer);
+
+ function setColorAlpha(color, alpha) {
+ var reg = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
+ var matches = reg.exec(color);
+ var r = parseInt(matches[1], 16);
+ var g = parseInt(matches[2], 16);
+ var b = parseInt(matches[3], 16);
+ return "rgba(".concat(r, ",").concat(g, ",").concat(b, ",").concat(alpha, ")");
+ }
+
+ function renderBoardIcon(board) {
+ if (board.icon) {
+ return "");
+ }
+
+ return '';
+ }
+
+ var BoardRenderer =
+ /*#__PURE__*/
+ function (_Renderer) {
+ _inherits(BoardRenderer, _Renderer);
+
+ function BoardRenderer() {
+ _classCallCheck(this, BoardRenderer);
+
+ return _possibleConstructorReturn(this, _getPrototypeOf(BoardRenderer).apply(this, arguments));
+ }
+
+ _createClass(BoardRenderer, [{
+ key: "render",
+ value: function render(board) {
+ return "\n
\n ").concat(this.renderHeader(board), "\n
\n
\n
\n
\n
\n
").concat(this.config.message.stateDisabled, "
\n
\n
\n
\n
");
+ }
+ }, {
+ key: "renderHeader",
+ value: function renderHeader(board) {
+ var headerStyle = '';
+ var headerClass = 'board-header';
+
+ if (board.color) {
+ if (board.colorTarget === 'background') {
+ headerStyle = "background-color: ".concat(setColorAlpha(board.color, 0.04));
+ } else {
+ headerClass += ' has-border';
+ headerStyle = "border-color: ".concat(board.color);
+ }
+ }
+
+ return "");
+ }
+ }, {
+ key: "renderActions",
+ value: function renderActions() {
+ var config = this.config;
+ var actions = config.actions;
+
+ if (typeof actions === 'function') {
+ actions = actions(config);
+ }
+
+ return "\n ").concat(actions.map(function (a) {
+ return "");
+ }).join(''), "\n
");
+ }
+ }, {
+ key: "renderAvatar",
+ value: function renderAvatar(board) {
+ if (!board.avatarUrl) {
+ return '';
+ }
+
+ return "
");
+ }
+ }, {
+ key: "renderTip",
+ value: function renderTip(board) {
+ var msg = this.config.message;
+
+ if (board.loadable) {
+ return "\n \n ".concat(msg.loading, "\n ");
+ }
+
+ if (board.completed && board.issues.length > 0) {
+ return "".concat(msg.allComplete, "");
+ }
+
+ return "".concat(msg.empty, "");
+ }
+ }]);
+
+ return BoardRenderer;
+ }(Renderer);
+ var Board =
+ /*#__PURE__*/
+ function () {
+ function Board(data, config) {
+ var _this = this;
+
+ _classCallCheck(this, Board);
+
+ this.page = 0;
+ this.loadable = true;
+ this.loading = false;
+ this.completed = false;
+ this.issues = [];
+ this.name = data.name;
+ this.icon = data.icon;
+ this.state = data.state;
+ this.color = data.color;
+ this.colorTarget = data.colorTarget;
+ this.issuesCount = data.issuesCount || 0;
+ this.avatarUrl = data.avatarUrl;
+ this.config = config;
+ this.renderer = new BoardRenderer(config);
+ this.cardRenderer = new CardRenderer(config);
+ this.$tip = null;
+ this.$el = $(this.renderer.render(this));
+ this.$dimmer = this.$el.find('.ui.dimmer');
+ this.$issues = this.$el.find('.board-list');
+ this.$issuesCount = this.$el.find('.issues-count');
+ this.$issues.on('scroll', function () {
+ _this.autoload();
+ });
+ }
+
+ _createClass(Board, [{
+ key: "add",
+ value: function add(issue) {
+ this.issues.push(issue);
+ this.issuesCount += 1;
+ this.$issuesCount.text(this.issuesCount);
+ }
+ }, {
+ key: "find",
+ value: function find(id) {
+ for (var i = 0; i < this.issues.length; ++i) {
+ var issue = this.issues[i];
+
+ if (issue.id === id) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+ }, {
+ key: "get",
+ value: function get(id) {
+ var i = this.find(id);
+
+ if (i >= 0) {
+ return this.issues[i];
+ }
+
+ return null;
+ }
+ }, {
+ key: "remove",
+ value: function remove(id) {
+ var i = this.find(id);
+
+ if (i >= 0) {
+ this.issuesCount -= 1;
+ this.$issuesCount.text(this.issuesCount);
+ return this.issues.splice(i, 1);
+ }
+
+ return null;
+ }
+ }, {
+ key: "clear",
+ value: function clear() {
+ this.page = 0;
+ this.issues = [];
+ this.issuesCount = 0;
+ this.loading = false;
+ this.loadable = true;
+ this.completed = false;
+ this.$issuesCount.text(0);
+ this.$issues.empty();
+ this.$tip = null;
+ }
+ }, {
+ key: "autoload",
+ value: function autoload() {
+ if (this.completed) {
+ return;
+ }
+
+ if (!this.$tip || this.$tip.position().top < this.$issues.height()) {
+ this.load();
+ }
+ }
+ }, {
+ key: "load",
+ value: function load() {
+ if (this.loading) {
+ return false;
+ }
+
+ this.page += 1;
+ this.loading = true;
+
+ if (this.page === 1) {
+ this.$dimmer.addClass('active');
+ }
+
+ this.config.onLoad(this, this.onLoadDone.bind(this));
+ return true;
+ }
+ }, {
+ key: "onLoadDone",
+ value: function onLoadDone(issues, count) {
+ this.issuesCount = count;
+ this.$issuesCount.text(this.issuesCount);
+ this.appendIssues(issues);
+
+ if (this.issuesCount > 0) {
+ if (issues.length < 1 || this.issuesCount === issues.length) {
+ this.loadable = false;
+ this.completed = true;
+ } else {
+ this.loadable = true;
+ this.completed = false;
+ }
+ } else {
+ this.loadable = false;
+ this.completed = true;
+ }
+
+ if (this.page === 1) {
+ this.$dimmer.removeClass('active');
+ }
+
+ this.loading = false;
+ this.updateTip();
+ this.autoload();
+ }
+ /* 进行初次加载 */
+
+ }, {
+ key: "firstload",
+ value: function firstload() {
+ if (this.page > 0) {
+ return false;
+ }
+
+ return this.load();
+ }
+ /**
+ * 更新提示
+ */
+
+ }, {
+ key: "updateTip",
+ value: function updateTip() {
+ if (this.$tip) {
+ this.$tip.remove();
+ }
+
+ this.$tip = $(this.renderer.renderTip(this));
+ this.$issues.append(this.$tip);
+ }
+ }, {
+ key: "createCard",
+ value: function createCard(issue) {
+ var $card = $(this.cardRenderer.render(issue));
+ var onSelect = this.config.onSelect;
+
+ if (onSelect) {
+ $card.on('click', function (e) {
+ var $target = $(e.target);
+
+ if (!$target.is('a')) {
+ $target = $target.parent();
+ }
+
+ if (!$target.parent().hasClass('card-header') && $target.is('a') && $target.attr('href')) {
+ return;
+ }
+
+ onSelect(issue, e);
+ });
+ }
+
+ return this.config.onRender(issue, $card, this.config);
+ }
+ }, {
+ key: "appendIssue",
+ value: function appendIssue(issue) {
+ this.issues.push(issue);
+ this.$issues.append(this.createCard(issue));
+ }
+ }, {
+ key: "prependIssue",
+ value: function prependIssue(issue) {
+ this.issuesCount += 1;
+ this.issues.splice(0, 0, issue);
+ this.$issues.prepend(this.createCard(issue));
+ this.$issuesCount.text(this.issuesCount);
+ }
+ }, {
+ key: "updateIssue",
+ value: function updateIssue(issue) {
+ var $issue = $("#".concat(this.config.name, "-issue-").concat(issue.id));
+
+ if ($issue.length < 1) {
+ this.prependIssue(issue);
+ return;
+ }
+
+ $issue.before(this.createCard(issue)).remove();
+ }
+ /**
+ * 直接追加多个任务,不更新任务总数
+ * @param {Array} issues 任务列表
+ */
+
+ }, {
+ key: "appendIssues",
+ value: function appendIssues(issues) {
+ var _this2 = this;
+
+ issues.filter(function (issue) {
+ return _this2.issues.every(function (boardIssue) {
+ return boardIssue.id !== issue.id;
+ });
+ }).forEach(function (issue) {
+ issue[_this2.config.Key] = _this2.state;
+
+ _this2.appendIssue(issue);
+ });
+ }
+ }]);
+
+ return Board;
+ }();
+
+ var Boards =
+ /*#__PURE__*/
+ function () {
+ /**
+ * 创建一个看板
+ * @param {JQuery} $el 看板容器元素
+ * @param {BoardsSettings} options 配置
+ */
+ function Boards($el, options) {
+ _classCallCheck(this, Boards);
+
+ var config = new Config(options);
+ this.$el = $el;
+ this.config = config;
+ this.boards = {};
+ this.$hoverIssue = null;
+ this.$selectedIssue = null;
+ this.timerForScrollLoad = null;
+ this.bindDrag();
+ this.bindScroll();
+ this.initPlugins();
+ this.setData(config.data);
+ }
+
+ _createClass(Boards, [{
+ key: "initPlugins",
+ value: function initPlugins() {
+ this.initSortable();
+ } // 初始化拖拽排序功能
+
+ }, {
+ key: "initSortable",
+ value: function initSortable() {
+ var that = this;
+ var Sortable = that.config.plugins.Sortable; // 如果没有注入 SortableJS 依赖,则不启用这个功能
+
+ if (!Sortable) {
+ return false;
+ }
+
+ that.$el.addClass('boards-sortable');
+ that.sortable = Sortable.create(that.$el[0], {
+ handle: '.board-title',
+ dataIdAttr: 'data-state',
+ onUpdate: function onUpdate() {
+ that.config.onSorted(that.sortable.toArray());
+ }
+ });
+ that.$el.on('click', '.board-action', function (e) {
+ var $target = $(this);
+ var id = $target.data('id');
+ var state = $target.parents('.board').data('state');
+ var actions = that.config.actions;
+
+ if (typeof actions === 'function') {
+ actions = actions(that.config);
+ }
+
+ actions.some(function (action) {
+ if (action.id === id && action.callback) {
+ action.callback(that, that.boards[state], e);
+ return true;
+ }
+
+ return false;
+ });
+ });
+ return true;
+ }
+ }, {
+ key: "bindScroll",
+ value: function bindScroll() {
+ var that = this;
+ var timerForScrollLoad = null;
+
+ function onScrollLoad() {
+ if (timerForScrollLoad) {
+ clearTimeout(timerForScrollLoad);
+ }
+
+ timerForScrollLoad = setTimeout(function () {
+ timerForScrollLoad = null;
+ that.load();
+ }, 200);
+ }
+
+ $(window).on('resize', onScrollLoad);
+ this.$el.on('scroll', onScrollLoad);
+ }
+ }, {
+ key: "bindDrag",
+ value: function bindDrag() {
+ var that = this;
+
+ if (that.config.readonly) {
+ return;
+ }
+
+ that.$el.on('dragstart', '.card', function (e) {
+ var issueId = $(this).data('id');
+ var issue = that.getIssue(issueId);
+
+ if (issue) {
+ that.setFocus(issue.type, issue.state);
+ }
+
+ that.$selectedIssue = $(this);
+ e.originalEvent.dataTransfer.setData('text/plain', issueId);
+ e.stopPropagation();
+ });
+ that.$el.on('dragend', '.card', function () {
+ that.clearFocus();
+ });
+ that.$el.on('drop', '.board-list', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ if (that.$hoverIssue) {
+ that.$hoverIssue.removeClass('card-dragover');
+ }
+
+ if (!that.$selectedIssue) {
+ return false;
+ }
+
+ if (that.config.readonly) {
+ return false;
+ }
+
+ var $issue = that.$selectedIssue;
+ var issueId = $issue.data('id');
+ var $board = $(this).parents('.board');
+ var state = $board.data('state');
+ var oldState = $issue.parents('.board').data('state');
+ var nextIssueId = that.$hoverIssue ? that.$hoverIssue.data('id') : null;
+ that.setIssueState(issueId, state, nextIssueId, function _callee(issue) {
+ return regenerator.async(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ return _context.abrupt("return", that.config.onUpdate(issue, oldState, nextIssueId));
+
+ case 1:
+ case "end":
+ return _context.stop();
+ }
+ }
+ });
+ });
+ return true;
+ });
+ that.$el.on('dragover', '.board-list', function (e) {
+ var key = that.config.key;
+ var $target = $(e.target);
+
+ if (!that.$selectedIssue) {
+ return;
+ }
+
+ e.preventDefault();
+
+ while ($target.length > 0 && !$target.hasClass('card')) {
+ $target = $target.parent();
+ }
+
+ if ($target.length < 1) {
+ if (that.$hoverIssue) {
+ that.$hoverIssue.removeClass('card-dragover');
+ }
+
+ that.$hoverIssue = null;
+ return;
+ }
+
+ if (that.$hoverIssue) {
+ that.$hoverIssue.removeClass('card-dragover');
+ }
+
+ that.$hoverIssue = $target;
+ var hoverIssue = that.getIssue($target.data('id'));
+ var selectedIssue = that.getIssue(that.$selectedIssue.data('id'));
+
+ if (hoverIssue && selectedIssue && hoverIssue[key] !== selectedIssue[key]) {
+ that.$hoverIssue.addClass('card-dragover');
+ }
+ });
+ }
+ /**
+ * 设置焦点板块
+ * 根据指定的类型和状态,排除无关状态的板块
+ * @param {String, Number} typeId 任务类型 id
+ * @param {String, Number} stateId 任务状态 id
+ */
+
+ }, {
+ key: "setFocus",
+ value: function setFocus(typeId, stateId) {
+ var _this = this;
+
+ var stateIds = [];
+ var issueType = null;
+
+ if (this.config.key !== 'state') {
+ return;
+ }
+
+ this.config.types.some(function (t) {
+ if (t.id === typeId) {
+ issueType = t;
+ return true;
+ }
+
+ return false;
+ });
+
+ if (issueType) {
+ stateIds = issueType.states.map(function (state) {
+ return state.id.toString();
+ });
+ }
+
+ Object.keys(this.boards).forEach(function (id) {
+ if (id !== stateId.toString() && stateIds.indexOf(id) === -1) {
+ _this.boards[id].$el.addClass('board-blur');
+ }
+ });
+ }
+ /* 清除板块的焦点效果 */
+
+ }, {
+ key: "clearFocus",
+ value: function clearFocus() {
+ var _this2 = this;
+
+ Object.keys(this.boards).forEach(function (key) {
+ _this2.boards[key].$el.removeClass('board-blur');
+ });
+ }
+ }, {
+ key: "getIssueCard",
+ value: function getIssueCard(id) {
+ return $("#".concat(this.config.name, "-issue-").concat(id));
+ }
+ }, {
+ key: "getIssue",
+ value: function getIssue(id) {
+ var $issue = this.getIssueCard(id);
+ var $board = $issue.parents('.board');
+ var state = $board.data('state');
+ var board = this.boards[state];
+
+ if (board) {
+ return board.get(id);
+ }
+
+ return null;
+ }
+ }, {
+ key: "removeIssue",
+ value: function removeIssue(id) {
+ var issue = null;
+ var $issue = this.getIssueCard(id);
+
+ if ($issue.length < 1) {
+ return issue;
+ }
+
+ var state = $issue.parents('.board').data('state');
+
+ if (state) {
+ var board = this.boards[state];
+
+ if (board) {
+ issue = board.remove(id);
+ }
+ }
+
+ $issue.remove();
+ return issue;
+ }
+ }, {
+ key: "updateIssue",
+ value: function updateIssue(issue) {
+ var board = this.boards[issue[this.config.key]];
+
+ if (board) {
+ board.updateIssue(issue);
+ return true;
+ }
+
+ return false;
+ }
+ }, {
+ key: "prependIssue",
+ value: function prependIssue(issue) {
+ var board = this.boards[issue[this.config.key]];
+
+ if (board) {
+ board.prependIssue(issue);
+ return true;
+ }
+
+ return false;
+ }
+ }, {
+ key: "setIssueState",
+ value: function setIssueState(issueId, state, nextIssueId, callback) {
+ var $issue = this.getIssueCard(issueId);
+ var $nextIssue = nextIssueId ? this.getIssueCard(nextIssueId) : null;
+
+ if ($issue.length < 1) {
+ return null;
+ }
+
+ var user = this.config.user;
+ var $oldBoard = $issue.parents('.board');
+ var oldState = $oldBoard.data('state');
+ var oldBoard = this.boards[oldState];
+ var newBoard = this.boards[state];
+
+ if (oldBoard.state === state) {
+ return null;
+ } // 如果新的板块不接受该状态的 issue
+
+
+ if (newBoard.exclude && newBoard.exclude.indexOf(oldState) >= 0) {
+ return null;
+ }
+
+ var issue = oldBoard.get(issueId); // 如果当前用户既不具备管理权限,也不是 issue 作者,则禁止操作
+
+ if (!user.admin && issue.author.id !== user.id) {
+ return null;
+ }
+
+ issue[this.config.key] = state;
+ newBoard.add(issue);
+ oldBoard.remove(issue.id);
+ $issue.hide(256, function () {
+ // 如果有指定下一个 issue,则将当前 issue 插入到它前面
+ if ($nextIssue) {
+ $nextIssue.before($issue);
+ } else {
+ newBoard.$issues.prepend($issue);
+ }
+
+ $issue.addClass('card-loading');
+ $issue.show(256, function _callee2() {
+ return regenerator.async(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ if (!callback) {
+ _context2.next = 3;
+ break;
+ }
+
+ _context2.next = 3;
+ return regenerator.awrap(callback(issue));
+
+ case 3:
+ $issue.removeClass('card-loading');
+
+ case 4:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ });
+ });
+ });
+ newBoard.updateTip();
+ oldBoard.updateTip();
+ oldBoard.autoload();
+ return issue;
+ }
+ }, {
+ key: "load",
+ value: function load() {
+ var _this3 = this;
+
+ var count = 0;
+ var bound = this.$el.offset(); // 设置边界框(可见区域)的尺寸
+
+ bound.width = this.$el.width();
+ bound.height = this.$el.height();
+ Object.keys(this.boards).forEach(function (state) {
+ var board = _this3.boards[state];
+ var offset = board.$el.offset(); // 如果当前板块在可见区域内
+
+ if (offset.top + board.$el.height() > bound.top && offset.left + board.$el.width() > bound.left && offset.top < bound.top + bound.height && offset.left < bound.left + bound.width) {
+ if (board.firstload()) {
+ count += 1;
+ }
+ }
+ });
+ return count;
+ }
+ }, {
+ key: "setData",
+ value: function setData(data) {
+ var _this4 = this;
+
+ this.boards = {};
+ this.$el.addClass('boards-list').empty();
+ data.forEach(function (boardData) {
+ var board = new Board(boardData, _this4.config);
+ _this4.boards[boardData.state] = board;
+
+ _this4.$el.append(board.$el);
+ });
+ }
+ }, {
+ key: "clearData",
+ value: function clearData() {
+ var _this5 = this;
+
+ Object.keys(this.boards).forEach(function (state) {
+ _this5.boards[state].clear();
+ });
+ }
+ }]);
+
+ return Boards;
+ }();
+
+ $.fn.boards = function (options) {
+ var that = this.data('boards');
+ var settings = $.extend({}, $.fn.boards.settings, options);
+
+ if (!that) {
+ that = new Boards(this, settings);
+ this.data('boards', that);
+ that.load();
+ }
+
+ return this;
+ };
+
+ $.fn.boards.settings = defaults;
}());
diff --git a/app/assets/stylesheets/gitee-frontend/components/boards.css b/app/assets/stylesheets/gitee-frontend/components/boards.css
index 6f6f182e83c1ec869ce98cacf61e0bdcf01e11e2..1d9f0477ebfeae0db6b3493560affe04e04dedf3 100644
--- a/app/assets/stylesheets/gitee-frontend/components/boards.css
+++ b/app/assets/stylesheets/gitee-frontend/components/boards.css
@@ -78,17 +78,35 @@
padding-right: 3em;
}
+.boards-list .board-list .card-loading {
+ position: relative;
+ pointer-events: none;
+}
+
+.boards-list .board-list .card-loading::before {
+ content: '';
+ top: 0;
+ left: 0;
+ z-index: 1;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ background: rgba(255, 255, 255, 0.8);
+}
+
.boards-list .board-list .button-wrapper {
padding: 10px;
text-align: center;
}
-.boards-list .board-list .card[draggable="true"], .boards-list .board-list .card-draggable {
+.boards-list .board-list .card[draggable="true"],
+.boards-list .board-list .card-draggable {
cursor: move;
cursor: -webkit-grab;
}
-.boards-list .board-list .card[draggable="true"]:active, .boards-list .board-list .card-draggable:active {
+.boards-list .board-list .card[draggable="true"]:active,
+.boards-list .board-list .card-draggable:active {
cursor: -webkit-grabbing;
}
@@ -125,6 +143,7 @@
}
.boards-list .board-list .labels {
+ margin-bottom: 16px;
font-size: smaller;
}
@@ -137,6 +156,10 @@
margin: 0.4em 0.4em 0 0;
}
+.boards-list .board-list .labels:empty {
+ margin-bottom: 0px;
+}
+
.boards-list .board-list .assignee,
.boards-list .board-list .state {
right: 1em;