diff --git a/config/config.php b/config/config.php
index 177c75257d..ed291616ba 100644
--- a/config/config.php
+++ b/config/config.php
@@ -168,6 +168,7 @@ define('TABLE_HISTORY', '`' . $config->db->prefix . 'history`');
define('TABLE_EXTENSION', '`' . $config->db->prefix . 'extension`');
define('TABLE_CRON', '`' . $config->db->prefix . 'cron`');
define('TABLE_MAILQUEUE', '`' . $config->db->prefix . 'mailqueue`');
+define('TABLE_BLOCK', '`' . $config->db->prefix . 'block`');
if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`');
$config->objectTables['product'] = TABLE_PRODUCT;
diff --git a/db/update8.1.3.sql b/db/update8.1.3.sql
index e7e3635db4..541a333c9c 100644
--- a/db/update8.1.3.sql
+++ b/db/update8.1.3.sql
@@ -1,2 +1,17 @@
ALTER TABLE `zt_module` ADD `short` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `owner`;
ALTER TABLE `zt_usertpl` ADD `public` enum('0','1') COLLATE 'utf8_general_ci' NOT NULL DEFAULT '0';
+CREATE TABLE `zt_block` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `account` char(30) NOT NULL,
+ `module` varchar(20) NOT NULL,
+ `title` varchar(100) NOT NULL,
+ `source` varchar(20) NOT NULL,
+ `block` varchar(20) NOT NULL,
+ `params` text NOT NULL,
+ `order` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `grid` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `hidden` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `accountModuleOrder` (`account`,`module`,`order`),
+ KEY `block` (`account`,`module`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/module/block/config.php b/module/block/config.php
new file mode 100644
index 0000000000..516f53315e
--- /dev/null
+++ b/module/block/config.php
@@ -0,0 +1,20 @@
+
+ * @package block
+ * @version $Id$
+ * @link http://www.ranzhico.com
+ */
+$config->block->editor = new stdclass();
+$config->block->editor->set = array('id' => 'html', 'tools' => 'simple');
+
+$config->block->gridOptions[6] = '1/2';
+$config->block->gridOptions[4] = '1/3';
+$config->block->gridOptions[8] = '2/3';
+$config->block->gridOptions[3] = '1/4';
+$config->block->gridOptions[9] = '3/4';
+$config->block->gridOptions[12] = '100%';
diff --git a/module/block/control.php b/module/block/control.php
index f98a860014..25b1c14804 100644
--- a/module/block/control.php
+++ b/module/block/control.php
@@ -20,7 +20,81 @@ class block extends control
public function __construct()
{
parent::__construct();
- if(!$this->loadModel('sso')->checkKey()) die('');
+ $this->blockModule = strpos($this->server->http_referer, common::getSysURL()) === 0 ? $this->session->blockModule : '';
+ if($this->methodName != 'admin' and empty($this->blockModule) and !$this->loadModel('sso')->checkKey()) die('');
+ }
+
+ /**
+ * Block admin.
+ *
+ * @param int $index
+ * @param string $module
+ * @access public
+ * @return void
+ */
+ public function admin($index = 0, $module = 'my')
+ {
+ $this->session->set('blockModule', $module);
+
+ $title = $index == 0 ? $this->lang->block->createBlock : $this->lang->block->editBlock;
+
+ if(!$index) $index = $this->block->getLastKey($module) + 1;
+
+ $modules = $this->lang->block->moduleList;
+ foreach($modules as $moduleKey => $moduleName)
+ {
+ if(in_array($moduleKey, $this->app->user->rights['acls'])) unset($modules[$moduleKey]);
+ if(!common::hasPriv($moduleKey, 'index')) unset($modules[$moduleKey]);
+ }
+
+ $modules['dynamic'] = $this->lang->block->dynamic;
+ $modules['html'] = 'HTML';
+ $modules = array('' => '') + $modules;
+
+ $hiddenBlocks = $this->block->getHiddenBlocks();
+ foreach($hiddenBlocks as $block) $modules['hiddenBlock' . $block->id] = $block->title;
+
+ $this->view->block = $this->block->getBlock($index);
+ $this->view->modules = $modules;
+ $this->view->index = $index;
+ $this->view->title = $title;
+ $this->display();
+ }
+
+ /**
+ * Set params when type is rss or html.
+ *
+ * @param int $index
+ * @param string $type
+ * @param int $blockID
+ * @access public
+ * @return void
+ */
+ public function set($index, $type, $blockID = 0)
+ {
+ if($_POST)
+ {
+ $source = isset($this->lang->block->moduleList[$type]) ? $type : '';
+ $this->block->save($index, $source, $this->blockModule, $blockID);
+ if(dao::isError()) die(js::error(dao::geterror()));
+ die(js::reload('parent'));
+ }
+
+ $block = $blockID ? $this->block->getByID($blockID) : $this->block->getBlock($index);
+ if($block) $type = $block->block;
+
+ if(isset($this->lang->block->moduleList[$type]))
+ {
+ $func = 'get' . ucfirst($blockID) . 'Params';
+ $params = $this->block->$func($type);
+ $this->view->params = json_decode($params, true);
+ }
+
+ $this->view->type = $type;
+ $this->view->index = $index;
+ $this->view->blockID = $blockID;
+ $this->view->block = ($block) ? $block : array();
+ $this->display();
}
/**
@@ -29,23 +103,37 @@ class block extends control
* @access public
* @return void
*/
- public function main()
+ public function main($module = '', $index = 0)
{
- $lang = $this->get->lang;
- $this->app->setClientLang($lang);
- $this->app->loadLang('common');
- $this->app->loadLang('block');
+ if(empty($this->blockModule))
+ {
+ $lang = $this->get->lang;
+ $this->app->setClientLang($lang);
+ $this->app->loadLang('common');
+ $this->app->loadLang('block');
+ }
$mode = strtolower($this->get->mode);
if($mode == 'getblocklist')
{
- echo $this->block->getAvailableBlocks();
+ $blocks = $this->block->getAvailableBlocks($module);
+ if($this->blockModule)
+ {
+ $blocks = json_decode($blocks, true);
+ $blockPairs = array('' => '') + $blocks;
+
+ $block = $this->block->getBlock($index);
+
+ echo "
{$this->lang->block->lblBlock} | ";
+ echo '' . html::select('moduleBlock', $blockPairs, ($block and $block->source != '') ? $block->block : '', "class='form-control' onchange='getBlockParams(this.value, \"$module\")'") . ' | ';
+ if(isset($block->source)) echo "";
+ }
}
elseif($mode == 'getblockform')
{
$code = strtolower($this->get->blockid);
$func = 'get' . ucfirst($code) . 'Params';
- echo $this->block->$func();
+ echo $this->block->$func($module);
}
elseif($mode == 'getblockdata')
{
@@ -69,7 +157,7 @@ class block extends control
$this->view->code = $this->get->blockid;
$func = 'print' . ucfirst($code) . 'Block';
- $this->$func();
+ $this->$func($module);
if($this->viewType == 'json')
{
diff --git a/module/block/css/admin.css b/module/block/css/admin.css
new file mode 100644
index 0000000000..0768b6323a
--- /dev/null
+++ b/module/block/css/admin.css
@@ -0,0 +1,5 @@
+.input-group-btn .dropdown-toggle {border-radius: 4px;}
+.dropdown-menu {min-width: 120px;}
+.dropdown-menu.colors {padding: 5px; width: 205px}
+.dropdown-menu.buttons {padding: 5px; padding-bottom: 0; padding-right: 0;}
+.dropdown-menu.buttons > li {margin-bottom: 5px; display: block; float: left; width: 33.333333%; padding-right: 5px}
diff --git a/module/block/js/admin.js b/module/block/js/admin.js
new file mode 100644
index 0000000000..b0a14227bb
--- /dev/null
+++ b/module/block/js/admin.js
@@ -0,0 +1,82 @@
+/**
+ * Get all blocks.
+ *
+ * @param string|int $moduleID
+ * @access public
+ * @return void
+ */
+function getBlocks(moduleID)
+{
+ var moduleBlock = $('#modules').parent().parent().next();
+ $(moduleBlock).hide();
+
+ $('#blockParam').empty();
+ if(moduleID == '') return false;
+
+ if(moduleID.indexOf('hiddenBlock') != -1)
+ {
+ getRssAndHtmlParams('html', moduleID.replace('hiddenBlock', ''));
+ return true;
+ }
+ if(moduleID == 'html' || moduleID == 'modules' || moduleID == 'dynamic')
+ {
+ getRssAndHtmlParams(moduleID);
+ return true;
+ }
+
+ $.get(createLink('block', 'main', 'module=' + moduleID + '&index=' + index), {mode:'getblocklist'}, function(data)
+ {
+ $(moduleBlock).html(data);
+ $(moduleBlock).show();
+ })
+}
+
+/**
+ * Get rss and html params.
+ *
+ * @param string $type
+ * @param int $blockID
+ * @access public
+ * @return void
+ */
+function getRssAndHtmlParams(type, blockID)
+{
+ blockID = typeof(blockID) == 'undefined' ? 0 : blockID;
+ $.get(createLink('block', 'set', 'index=' + index + '&type=' + type + '&blockID=' + blockID), function(data)
+ {
+ $('#blockParam').html(data);
+ });
+}
+
+/**
+ * Get block params.
+ *
+ * @param string $blockID
+ * @param int $moduleID
+ * @access public
+ * @return void
+ */
+function getBlockParams(blockID, moduleID)
+{
+ $('#blockParam').empty();
+ if(blockID == '') return false;
+
+ $.get(createLink('block', 'set', 'index=' + index + '&type=' + moduleID + '&blockID=' + blockID), function(data)
+ {
+ $('#blockParam').html(data);
+ });
+}
+
+$(function()
+{
+ $('#modules').change(function(){getBlocks($(this).val())});
+ getBlocks($('#modules').val());
+
+ $(document).on('click', '.dropdown-menu.buttons .btn', function()
+ {
+ var $this = $(this);
+ var group = $this.closest('.input-group-btn');
+ group.find('.dropdown-toggle').removeClass().addClass('btn dropdown-toggle btn-' + $this.data('id'));
+ group.find('input[name^="params[color]"]').val($this.data('id'));
+ });
+})
diff --git a/module/block/lang/en.php b/module/block/lang/en.php
index e176ca88e2..03330ed4f6 100644
--- a/module/block/lang/en.php
+++ b/module/block/lang/en.php
@@ -10,6 +10,100 @@
* @link http://www.ranzhi.org
*/
$lang->block = new stdclass();
+$lang->block->common = 'Block';
+$lang->block->name = 'Name';
+$lang->block->style = 'Style';
+$lang->block->grid = 'Grid';
+$lang->block->color = 'Color';
+
+$lang->block->lblModule = 'Module';
+$lang->block->lblBlock = 'Block';
+$lang->block->lblNum = 'Number';
+$lang->block->lblHtml = 'HTML Content';
+$lang->block->dynamic = 'Dynamic';
+
+$lang->block->params = new stdclass();
+$lang->block->params->name = 'Name';
+$lang->block->params->value = 'Value';
+
+$lang->block->createBlock = 'Add block';
+$lang->block->editBlock = 'Edit block';
+$lang->block->ordersSaved = 'Sort have been saved';
+$lang->block->confirmRemoveBlock = 'Are you sure remove block [{0}] ?';
+
+$lang->block->default['product']['1']['title'] = 'Story of assigned to me';
+$lang->block->default['product']['1']['block'] = 'story';
+$lang->block->default['product']['1']['grid'] = 4;
+
+$lang->block->default['product']['1']['params']['num'] = 15;
+$lang->block->default['product']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['product']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['product']['2']['title'] = $lang->productCommon . ' list';
+$lang->block->default['product']['2']['block'] = 'list';
+$lang->block->default['product']['2']['grid'] = 4;
+
+$lang->block->default['product']['2']['params']['num'] = 15;
+$lang->block->default['product']['2']['params']['type'] = 'noclosed';
+
+$lang->block->default['project']['1']['title'] = 'Task of assigned to me';
+$lang->block->default['project']['1']['block'] = 'task';
+$lang->block->default['project']['1']['grid'] = 4;
+
+$lang->block->default['project']['1']['params']['num'] = 15;
+$lang->block->default['project']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['project']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['project']['2']['title'] = $lang->projectCommon . ' list';
+$lang->block->default['project']['2']['block'] = 'list';
+$lang->block->default['project']['2']['grid'] = 4;
+
+$lang->block->default['project']['2']['params']['num'] = 15;
+$lang->block->default['project']['2']['params']['orderBy'] = 'id_desc';
+$lang->block->default['project']['2']['params']['type'] = 'undone';
+
+$lang->block->default['qa']['1']['title'] = 'Bug of assigned to me';
+$lang->block->default['qa']['1']['block'] = 'bug';
+$lang->block->default['qa']['1']['grid'] = 4;
+
+$lang->block->default['qa']['1']['params']['num'] = 15;
+$lang->block->default['qa']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['qa']['2']['title'] = 'Case of assigned to me';
+$lang->block->default['qa']['2']['block'] = 'case';
+$lang->block->default['qa']['2']['grid'] = 4;
+
+$lang->block->default['qa']['2']['params']['num'] = 15;
+$lang->block->default['qa']['2']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['2']['params']['type'] = 'assignedTo';
+
+$lang->block->default['qa']['3']['title'] = 'Waiting test task';
+$lang->block->default['qa']['3']['block'] = 'testtask';
+$lang->block->default['qa']['3']['grid'] = 4;
+
+$lang->block->default['qa']['3']['params']['num'] = 15;
+$lang->block->default['qa']['3']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['3']['params']['type'] = 'wait';
+
+$lang->block->default['my']['1'] = $lang->block->default['project']['2'];
+$lang->block->default['my']['1']['source'] = 'project';
+$lang->block->default['my']['2']['title'] = 'Dynamic';
+$lang->block->default['my']['2']['block'] = 'dynamic';
+$lang->block->default['my']['2']['grid'] = 6;
+$lang->block->default['my']['2']['source'] = '';
+$lang->block->default['my']['3'] = $lang->block->default['product']['2'];
+$lang->block->default['my']['3']['source'] = 'product';
+$lang->block->default['my']['4']['title'] = 'My todo';
+$lang->block->default['my']['4']['block'] = 'list';
+$lang->block->default['my']['4']['grid'] = 6;
+$lang->block->default['my']['4']['source'] = 'todo';
+$lang->block->default['my']['4']['params']['num'] = '20';
+$lang->block->default['my']['5'] = $lang->block->default['project']['1'];
+$lang->block->default['my']['5']['source'] = 'project';
+$lang->block->default['my']['6'] = $lang->block->default['qa']['1'];
+$lang->block->default['my']['6']['source'] = 'qa';
+
$lang->block->num = 'Number';
$lang->block->type = 'Type';
$lang->block->orderBy = 'Order';
@@ -24,6 +118,31 @@ $lang->block->availableBlocks->story = 'My story';
$lang->block->availableBlocks->product = $lang->productCommon;
$lang->block->availableBlocks->project = $lang->projectCommon;
+$lang->block->moduleList['product'] = $lang->productCommon;
+$lang->block->moduleList['project'] = $lang->projectCommon;
+$lang->block->moduleList['qa'] = '测试';
+$lang->block->moduleList['todo'] = '待办';
+
+$lang->block->modules['product'] = new stdclass();
+$lang->block->modules['product']->availableBlocks = new stdclass();
+$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表';
+$lang->block->modules['product']->availableBlocks->story = '需求列表';
+$lang->block->modules['product']->availableBlocks->plan = '计划列表';
+$lang->block->modules['product']->availableBlocks->release = '发布列表';
+$lang->block->modules['project'] = new stdclass();
+$lang->block->modules['project']->availableBlocks = new stdclass();
+$lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . '列表';
+$lang->block->modules['project']->availableBlocks->task = '任务列表';
+$lang->block->modules['project']->availableBlocks->build = '版本列表';
+$lang->block->modules['qa'] = new stdclass();
+$lang->block->modules['qa']->availableBlocks = new stdclass();
+$lang->block->modules['qa']->availableBlocks->bug = 'Bug列表';
+$lang->block->modules['qa']->availableBlocks->case = '用例列表';
+$lang->block->modules['qa']->availableBlocks->testtask = '版本列表';
+$lang->block->modules['todo'] = new stdclass();
+$lang->block->modules['todo']->availableBlocks = new stdclass();
+$lang->block->modules['todo']->availableBlocks->list = '待办列表';
+
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->task = array();
@@ -82,3 +201,14 @@ $lang->block->typeList->story['assignedTo'] = 'Assigned to';
$lang->block->typeList->story['openedBy'] = 'Opened by';
$lang->block->typeList->story['reviewedBy'] = 'Reviewed by';
$lang->block->typeList->story['closedBy'] = 'Closed by';
+
+$lang->block->typeList->product['noclosed'] = 'No closed';
+$lang->block->typeList->product['all'] = 'All';
+
+$lang->block->typeList->project['undone'] = 'Undone';
+$lang->block->typeList->project['isdoing'] = 'Doing';
+$lang->block->typeList->project['all'] = 'All';
+
+$lang->block->typeList->testtask['wait'] = 'Waiting test task';
+$lang->block->typeList->testtask['done'] = 'Done test task';
+$lang->block->typeList->testtask['all'] = 'All';
diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php
index 4c42af0674..2163e5d3d0 100644
--- a/module/block/lang/zh-cn.php
+++ b/module/block/lang/zh-cn.php
@@ -10,6 +10,100 @@
* @link http://www.ranzhi.org
*/
$lang->block = new stdclass();
+$lang->block->common = '区块';
+$lang->block->name = '区块名称';
+$lang->block->style = '外观';
+$lang->block->grid = '宽度';
+$lang->block->color = '颜色';
+
+$lang->block->lblModule = '模块';
+$lang->block->lblBlock = '区块';
+$lang->block->lblNum = '条数';
+$lang->block->lblHtml = 'HTML内容';
+$lang->block->dynamic = '最新动态';
+
+$lang->block->params = new stdclass();
+$lang->block->params->name = '参数名称';
+$lang->block->params->value = '参数值';
+
+$lang->block->createBlock = '添加区块';
+$lang->block->editBlock = '编辑区块';
+$lang->block->ordersSaved = '排序已保存';
+$lang->block->confirmRemoveBlock = '确定移除区块【{0}】吗?';
+
+$lang->block->default['product']['1']['title'] = '指派给我的需求';
+$lang->block->default['product']['1']['block'] = 'story';
+$lang->block->default['product']['1']['grid'] = 4;
+
+$lang->block->default['product']['1']['params']['num'] = 15;
+$lang->block->default['product']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['product']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['product']['2']['title'] = $lang->productCommon . '列表';
+$lang->block->default['product']['2']['block'] = 'list';
+$lang->block->default['product']['2']['grid'] = 4;
+
+$lang->block->default['product']['2']['params']['num'] = 15;
+$lang->block->default['product']['2']['params']['type'] = 'noclosed';
+
+$lang->block->default['project']['1']['title'] = '指派给我的任务';
+$lang->block->default['project']['1']['block'] = 'task';
+$lang->block->default['project']['1']['grid'] = 4;
+
+$lang->block->default['project']['1']['params']['num'] = 15;
+$lang->block->default['project']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['project']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['project']['2']['title'] = $lang->projectCommon . '列表';
+$lang->block->default['project']['2']['block'] = 'list';
+$lang->block->default['project']['2']['grid'] = 4;
+
+$lang->block->default['project']['2']['params']['num'] = 15;
+$lang->block->default['project']['2']['params']['orderBy'] = 'id_desc';
+$lang->block->default['project']['2']['params']['type'] = 'undone';
+
+$lang->block->default['qa']['1']['title'] = '指派给我的Bug';
+$lang->block->default['qa']['1']['block'] = 'bug';
+$lang->block->default['qa']['1']['grid'] = 4;
+
+$lang->block->default['qa']['1']['params']['num'] = 15;
+$lang->block->default['qa']['1']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['1']['params']['type'] = 'assignedTo';
+
+$lang->block->default['qa']['2']['title'] = '指派给我的用例';
+$lang->block->default['qa']['2']['block'] = 'case';
+$lang->block->default['qa']['2']['grid'] = 4;
+
+$lang->block->default['qa']['2']['params']['num'] = 15;
+$lang->block->default['qa']['2']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['2']['params']['type'] = 'assignedTo';
+
+$lang->block->default['qa']['3']['title'] = '待测版本列表';
+$lang->block->default['qa']['3']['block'] = 'testtask';
+$lang->block->default['qa']['3']['grid'] = 4;
+
+$lang->block->default['qa']['3']['params']['num'] = 15;
+$lang->block->default['qa']['3']['params']['orderBy'] = 'id_desc';
+$lang->block->default['qa']['3']['params']['type'] = 'wait';
+
+$lang->block->default['my']['1'] = $lang->block->default['project']['2'];
+$lang->block->default['my']['1']['source'] = 'project';
+$lang->block->default['my']['2']['title'] = '最新动态';
+$lang->block->default['my']['2']['block'] = 'dynamic';
+$lang->block->default['my']['2']['grid'] = 6;
+$lang->block->default['my']['2']['source'] = '';
+$lang->block->default['my']['3'] = $lang->block->default['product']['2'];
+$lang->block->default['my']['3']['source'] = 'product';
+$lang->block->default['my']['4']['title'] = '我的待办';
+$lang->block->default['my']['4']['block'] = 'list';
+$lang->block->default['my']['4']['grid'] = 6;
+$lang->block->default['my']['4']['source'] = 'todo';
+$lang->block->default['my']['4']['params']['num'] = '20';
+$lang->block->default['my']['5'] = $lang->block->default['project']['1'];
+$lang->block->default['my']['5']['source'] = 'project';
+$lang->block->default['my']['6'] = $lang->block->default['qa']['1'];
+$lang->block->default['my']['6']['source'] = 'qa';
+
$lang->block->num = '数量';
$lang->block->type = '类型';
$lang->block->orderBy = '排序';
@@ -24,6 +118,31 @@ $lang->block->availableBlocks->story = '我的需求';
$lang->block->availableBlocks->product = $lang->productCommon . '列表';
$lang->block->availableBlocks->project = $lang->projectCommon . '列表';
+$lang->block->moduleList['product'] = $lang->productCommon;
+$lang->block->moduleList['project'] = $lang->projectCommon;
+$lang->block->moduleList['qa'] = '测试';
+$lang->block->moduleList['todo'] = '待办';
+
+$lang->block->modules['product'] = new stdclass();
+$lang->block->modules['product']->availableBlocks = new stdclass();
+$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表';
+$lang->block->modules['product']->availableBlocks->story = '需求列表';
+$lang->block->modules['product']->availableBlocks->plan = '计划列表';
+$lang->block->modules['product']->availableBlocks->release = '发布列表';
+$lang->block->modules['project'] = new stdclass();
+$lang->block->modules['project']->availableBlocks = new stdclass();
+$lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . '列表';
+$lang->block->modules['project']->availableBlocks->task = '任务列表';
+$lang->block->modules['project']->availableBlocks->build = '版本列表';
+$lang->block->modules['qa'] = new stdclass();
+$lang->block->modules['qa']->availableBlocks = new stdclass();
+$lang->block->modules['qa']->availableBlocks->bug = 'Bug列表';
+$lang->block->modules['qa']->availableBlocks->case = '用例列表';
+$lang->block->modules['qa']->availableBlocks->testtask = '版本列表';
+$lang->block->modules['todo'] = new stdclass();
+$lang->block->modules['todo']->availableBlocks = new stdclass();
+$lang->block->modules['todo']->availableBlocks->list = '待办列表';
+
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->task = array();
@@ -82,3 +201,14 @@ $lang->block->typeList->story['assignedTo'] = '指派给我';
$lang->block->typeList->story['openedBy'] = '由我创建';
$lang->block->typeList->story['reviewedBy'] = '由我评审';
$lang->block->typeList->story['closedBy'] = '由我关闭';
+
+$lang->block->typeList->product['noclosed'] = '未关闭';
+$lang->block->typeList->product['all'] = '全部';
+
+$lang->block->typeList->project['undone'] = '未完成';
+$lang->block->typeList->project['isdoing'] = '进行中';
+$lang->block->typeList->project['all'] = '全部';
+
+$lang->block->typeList->testtask['wait'] = '待测版本';
+$lang->block->typeList->testtask['done'] = '已测版本';
+$lang->block->typeList->testtask['all'] = '全部';
diff --git a/module/block/model.php b/module/block/model.php
index 64808f0013..d05082e77c 100644
--- a/module/block/model.php
+++ b/module/block/model.php
@@ -11,26 +11,203 @@
*/
class blockModel extends model
{
+ /**
+ * Save params
+ *
+ * @param int $index
+ * @param string $type
+ * @param string $appName
+ * @param int $blockID
+ * @access public
+ * @return void
+ */
+ public function save($index, $source, $module = 'my', $blockID = 0)
+ {
+ $data = fixer::input('post')
+ ->add('account', $this->app->user->account)
+ ->add('order', $index)
+ ->add('module', $module)
+ ->add('hidden', 0)
+ ->setIF($blockID, 'id', $blockID)
+ ->setDefault('grid', '4')
+ ->setDefault('source', $source)
+ ->setDefault('params', array())
+ ->get();
+
+ $data->params = helper::jsonEncode($data->params);
+ $this->dao->replace(TABLE_BLOCK)->data($data)->exec();
+ }
+
+ /**
+ * Get block by ID.
+ *
+ * @param int $blockID
+ * @access public
+ * @return object
+ */
+ public function getByID($blockID)
+ {
+ $block = $this->dao->select('*')->from(TABLE_BLOCK)
+ ->where('id')->eq($blockID)
+ ->fetch();
+ if(empty($block)) return false;
+
+ $block->params = json_decode($block->params);
+ if(empty($block->params)) $block->params = new stdclass();
+ return $block;
+ }
+
+ /**
+ * Get saved block config.
+ *
+ * @param int $index
+ * @access public
+ * @return object
+ */
+ public function getBlock($index, $module = 'my')
+ {
+ $block = $this->dao->select('*')->from(TABLE_BLOCK)
+ ->where('`order`')->eq($index)
+ ->andWhere('account')->eq($this->app->user->account)
+ ->andWhere('module')->eq($module)
+ ->fetch();
+ if(empty($block)) return false;
+
+ $block->params = json_decode($block->params);
+ if(empty($block->params)) $block->params = new stdclass();
+ return $block;
+ }
+
+ /**
+ * Get last key.
+ *
+ * @param string $appName
+ * @access public
+ * @return int
+ */
+ public function getLastKey($module = 'my')
+ {
+ $index = $this->dao->select('`order`')->from(TABLE_BLOCK)
+ ->where('module')->eq($module)
+ ->andWhere('account')->eq($this->app->user->account)
+ ->orderBy('order desc')
+ ->limit(1)
+ ->fetch('order');
+ return $index ? $index : 0;
+ }
+
+ /**
+ * Get block list for account.
+ *
+ * @param string $appName
+ * @access public
+ * @return void
+ */
+ public function getBlockList($module = 'my')
+ {
+ $blocks = $this->dao->select('*')->from(TABLE_BLOCK)->where('account')->eq($this->app->user->account)
+ ->andWhere('module')->eq($module)
+ ->andWhere('hidden')->eq(0)
+ ->orderBy('`order`')
+ ->fetchAll('order');
+
+ foreach($blocks as $key => $block)
+ {
+ if(strpos('html,allEntries,dynamic', $block->block) !== false) continue;
+
+ $module = $block->block;
+ $method = 'browse';
+ if(!commonModel::hasPriv($module, $method)) unset($blocks[$key]);
+ }
+ return $blocks;
+ }
+
+ /**
+ * Get hidden blocks
+ *
+ * @access public
+ * @return array
+ */
+ public function getHiddenBlocks($module = 'my')
+ {
+ return $this->dao->select('*')->from(TABLE_BLOCK)->where('account')->eq($this->app->user->account)
+ ->andWhere('module')->eq($module)
+ ->andWhere('hidden')->eq(1)
+ ->orderBy('`order`')
+ ->fetchAll('order');
+ }
+
+ /**
+ * Init block when account use first.
+ *
+ * @param string $appName
+ * @access public
+ * @return bool
+ */
+ public function initBlock($module)
+ {
+ $blocks = $this->lang->block->default[$module];
+ $account = $this->app->user->account;
+
+ /* Mark this app has init. */
+ $this->loadModel('setting')->setItem("$account.$module.common.blockInited", true);
+ foreach($blocks as $index => $block)
+ {
+ $block['order'] = $index;
+ $block['module'] = $module;
+ $block['account'] = $account;
+ $block['params'] = isset($block['params']) ? helper::jsonEncode($block['params']) : '';
+ if(!isset($block['source'])) $block['source'] = $module;
+
+ $this->dao->replace(TABLE_BLOCK)->data($block)->exec();
+ }
+
+ return !dao::isError();
+ }
+
/**
* Get block list.
*
* @access public
* @return string
*/
- public function getAvailableBlocks()
+ public function getAvailableBlocks($module = '')
{
+ if($module and isset($this->lang->block->modules[$module]))return json_encode($this->lang->block->modules[$module]->availableBlocks);
return json_encode($this->lang->block->availableBlocks);
}
+ /**
+ * Get list params for product|project|todo
+ *
+ * @param string $module
+ * @access public
+ * @return void
+ */
+ public function getListParams($module = '')
+ {
+ $params = new stdclass();
+
+ if($module == 'project' or $module == 'product')
+ {
+ $params->type['name'] = $this->lang->block->type;
+ $params->type['options'] = $this->lang->block->typeList->$module;
+ $params->type['control'] = 'select';
+ }
+
+ $params = $this->onlyNumParams($module, $params);
+ return json_encode($params);
+ }
+
/**
* Get todo params.
*
* @access public
* @return json
*/
- public function getTodoParams()
+ public function getTodoParams($module = '')
{
- return $this->getProductParams();
+ return $this->getListParams($module);
}
/**
@@ -39,7 +216,7 @@ class blockModel extends model
* @access public
* @return string
*/
- public function getTaskParams()
+ public function getTaskParams($module = '')
{
$params = new stdclass();
$params->type['name'] = $this->lang->block->type;
@@ -64,7 +241,7 @@ class blockModel extends model
* @access public
* @return json
*/
- public function getBugParams()
+ public function getBugParams($module = '')
{
$params = new stdclass();
$params->type['name'] = $this->lang->block->type;
@@ -89,7 +266,7 @@ class blockModel extends model
* @access public
* @return json
*/
- public function getCaseParams()
+ public function getCaseParams($module = '')
{
$params = new stdclass();
$params->type['name'] = $this->lang->block->type;
@@ -108,13 +285,34 @@ class blockModel extends model
return json_encode($params);
}
+ /**
+ * Get testtask params.
+ *
+ * @param string $module
+ * @access public
+ * @return void
+ */
+ public function getTesttaskParams($module = '')
+ {
+ $params = new stdclass();
+ $params->type['name'] = $this->lang->block->type;
+ $params->type['options'] = $this->lang->block->typeList->testtask;
+ $params->type['control'] = 'select';
+
+ $params->num['name'] = $this->lang->block->num;
+ $params->num['default'] = 20;
+ $params->num['control'] = 'input';
+
+ return json_encode($params);
+ }
+
/**
* Get story params.
*
* @access public
* @return json
*/
- public function getStoryParams()
+ public function getStoryParams($module = '')
{
$params = new stdclass();
$params->type['name'] = $this->lang->block->type;
@@ -133,20 +331,51 @@ class blockModel extends model
return json_encode($params);
}
+ /**
+ * Get plan params.
+ *
+ * @access public
+ * @return json
+ */
+ public function getPlanParams($module = '')
+ {
+ $params = $this->onlyNumParams($module);
+ return json_encode($params);
+ }
+
+ /**
+ * Get Release params.
+ *
+ * @access public
+ * @return json
+ */
+ public function getReleaseParams($module = '')
+ {
+ $params = $this->onlyNumParams($module);
+ return json_encode($params);
+ }
+
+ /**
+ * Get Build params.
+ *
+ * @access public
+ * @return json
+ */
+ public function getBuildParams($module = '')
+ {
+ $params = $this->onlyNumParams($module);
+ return json_encode($params);
+ }
+
/**
* Get product params.
*
* @access public
* @return json
*/
- public function getProductParams()
+ public function getProductParams($module = '')
{
- $params = new stdclass();
- $params->num['name'] = $this->lang->block->num;
- $params->num['default'] = 20;
- $params->num['control'] = 'input';
-
- return json_encode($params);
+ return $this->getListParams($module);
}
/**
@@ -155,8 +384,25 @@ class blockModel extends model
* @access public
* @return json
*/
- public function getProjectParams()
+ public function getProjectParams($module = '')
{
- return $this->getProductParams();
+ return $this->getListParams($module);
+ }
+
+ /**
+ * Build number params.
+ *
+ * @param string $module
+ * @param object $params
+ * @access public
+ * @return object
+ */
+ public function onlyNumParams($module = '', $params = '')
+ {
+ if(empty($params)) $params = new stdclass();
+ $params->num['name'] = $this->lang->block->num;
+ $params->num['default'] = 20;
+ $params->num['control'] = 'input';
+ return $params;
}
}
diff --git a/module/block/view/admin.html.php b/module/block/view/admin.html.php
new file mode 100644
index 0000000000..4c6fa47fa4
--- /dev/null
+++ b/module/block/view/admin.html.php
@@ -0,0 +1,27 @@
+
+ * @package block
+ * @version $Id$
+ * @link http://www.ranzhico.com
+ */
+?>
+
+
+
+
+
diff --git a/module/block/view/publicform.html.php b/module/block/view/publicform.html.php
new file mode 100644
index 0000000000..a98733c423
--- /dev/null
+++ b/module/block/view/publicform.html.php
@@ -0,0 +1,42 @@
+
+ * @package block
+ * @version $Id$
+ * @link http://www.zentao.net
+ */
+?>
+
+ | block->name?> |
+ title : '', "class='form-control'")?> |
+
+
+ | block->style;?> |
+
+
+ |
+
diff --git a/module/block/view/set.html.php b/module/block/view/set.html.php
new file mode 100644
index 0000000000..09bfc87aa9
--- /dev/null
+++ b/module/block/view/set.html.php
@@ -0,0 +1,40 @@
+
+ * @package block
+ * @version $Id$
+ * @link http://www.ranzhico.com
+ */
+?>
+block->moduleList[$type]))
+{
+ include 'setmodule.html.php';
+ die();
+}
+if($type == 'html')
+{
+ $webRoot = $config->webRoot;
+ $jsRoot = $webRoot . "js/";
+ $themeRoot = $webRoot . "theme/";
+ include '../../common/view/kindeditor.html.php';
+}
+?>
+
diff --git a/module/block/view/setmodule.html.php b/module/block/view/setmodule.html.php
new file mode 100644
index 0000000000..4ec21026d9
--- /dev/null
+++ b/module/block/view/setmodule.html.php
@@ -0,0 +1,69 @@
+
+ * @package block
+ * @version $Id: html.php 7488 2013-12-26 07:26:10Z zhujinyong $
+ * @link http://www.ranzhico.com
+ */
+?>
+webRoot;
+$jsRoot = $webRoot . "js/";
+$themeRoot = $webRoot . "theme/";
+include "../../common/view/chosen.html.php";
+?>
+
+name)):?>
+
+