+ Display chart in open source version.

This commit is contained in:
liugang
2023-04-06 10:12:08 +00:00
parent adc8d2d267
commit 492c01807f
33 changed files with 2383 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
<?php
$config->chart->widthInput = 128;
$config->chart->widthDate = 248;
$config->chart->dateConvert = array();
$config->chart->dateConvert['year'] = 'YEAR';
$config->chart->dateConvert['month'] = 'MONTH';
$config->chart->dateConvert['week'] = 'YEARWEEK';
$config->chart->dateConvert['day'] = 'DATE';
+257
View File
@@ -0,0 +1,257 @@
<?php
/**
* The control file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chart extends control
{
/**
* Preview charts of a group.
*
* @param int $dimensionID
* @param int $groupID
* @access public
* @return void
*/
public function preview($dimensionID = 0, $groupID = 0)
{
$dimensionID = $this->loadModel('dimension')->setSwitcherMenu($dimensionID);
if(!$groupID) $groupID = $this->chart->getFirstChartGroupID($dimensionID);
list($chartTree, $charts) = $this->chart->getPreviewCharts($groupID);
if(!empty($_POST))
{
$charts = array();
foreach($this->post->charts as $value)
{
$chartID = explode('_', $value);
$group = $chartID[0];
$chartID = $chartID[1];
$chart = $this->chart->getByID($chartID);
$chart->currentGroup = $group;
$charts[] = $chart;
}
}
$this->view->title = $this->lang->chart->preview;
$this->view->dimensionID = $dimensionID;
$this->view->group = $this->loadModel('tree')->getByID($groupID);
$this->view->chartTree = $chartTree;
$this->view->charts = $charts;
$this->view->groups = $this->loadModel('tree')->getGroupPairs($dimensionID, 0, 1);
$this->display();
}
/**
* Ajax get filter form html.
*
* @param int $chartID
* @access public
* @return string
*/
public function ajaxGetFilterForm($chartID)
{
$fieldList = $this->post->fieldList;
$filters = $this->post->filters;
$fieldSettings = $this->post->fieldSettings;
$langs = $this->post->langs;
$clientLang = $this->app->getClientLang();
$fieldPairs = array();
foreach($fieldList as $field => $fieldName)
{
$fieldObject = $fieldSettings[$field]['object'];
$relatedField = $fieldSettings[$field]['field'];
$this->app->loadLang($fieldObject);
$fieldPairs[$field] = isset($this->lang->$fieldObject->$relatedField) ? $this->lang->$fieldObject->$relatedField : $field;
if(!isset($langs[$field])) continue;
if(!empty($langs[$field][$clientLang])) $fieldPairs[$field] = $langs[$field][$clientLang];
}
$htmls = array();
foreach($filters as $filter)
{
$field = $filter['field'];
$type = $filter['type'];
$default = isset($filter['default']) ? $filter['default'] : '';
$options = array();
if($type == 'select')
{
$fieldSetting = $fieldSettings[$field];
$options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''));
}
$filterHtml = array();
/* field html */
$filterHtml['field'] = html::select('field', $fieldPairs, $field, "class='form-control picker-select' onchange='initFilterForm(this, this.value)'");
/* default html */
$filterHtml['default'] = '';
if($type == 'input') $filterHtml['default'] .= html::input('default', $default, "class='form-control' onchange='changeDefault(this,this.value)'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['default'] .= '<div class="input-group">';
$filterHtml['default'] .= html::input('default[begin]', $default['begin'], "class='form-control $class default-begin' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= "<span class='input-group-addon fix-border borderBox' style='border-radius: 0px;'>{$this->lang->chart->colon}</span>";
$filterHtml['default'] .= html::input('default[end]', $default['end'], "class='form-control $class default-end' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= '</div>';
}
if($type == 'select') $filterHtml['default'] = html::select('default[]', $options, $default, "class='form-control picker-select' onchange='changeDefault(this,this.value)' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['default'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['default'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value)'");
$filterHtml['default'] .= html::input('value', $value, "class='form-control $hidden' onchange='changeConditionValue(this,this.value)'");
$filterHtml['default'] .= "<div/>";
}
/* type html */
$filterHtml['type'] = html::select('type', $this->lang->chart->fieldTypeList, $type, "class='form-control picker-select' onchange='changeType(this, this.value)'");
/* filter item html */
$filterHtml['item'] = '';
if($type == 'input') $filterHtml['item'] .= html::input('default', $default, "class='form-control'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['item'] .= '<div class="input-group">';
$filterHtml['item'] .= "<input type='text' name='default[begin]' id='default[begin]' value='{$default['begin']}' class='form-control $class default-begin' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '<span class="input-group-addon fix-border borderBox" style="border-radius: 0px;">' . $this->lang->chart->colon . '</span>';
$filterHtml['item'] .= "<input type='text' name='default[end]' id='default[end]' value='{$default['end']}' class='form-control $class default-end' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '</div>';
}
if($type == 'select') $filterHtml['item'] .= html::select('default', array('' => '') + $options, $default, "class='form-control picker-select' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['item'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['item'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value, true)'");
$filterHtml['item'] .= html::input('value', $value, "class='form-control $hidden'");
$filterHtml['item'] .= "<div/>";
}
$htmls[] = $filterHtml;
}
echo json_encode($htmls);
}
/**
* Ajax get chart.
*
* @access public
* @return void
*/
public function ajaxGetChart()
{
$post = fixer::input('post')->skipSpecial('settings,filters,sql,langs')->get();
$chartID = $post->id;
$settings = current($post->settings);
$type = $settings['type'];
$filters = isset($_POST['searchFilters']) ? $_POST['searchFilters'] : (isset($_POST['filters']) ? $post->filters : array());
$chart = $this->chart->getByID($chartID);
$filterFormat = array();
foreach($filters as $filter)
{
$field = $filter['field'];
if(!isset($filter['default'])) continue;
$default = $filter['default'];
switch($filter['type'])
{
case 'select':
if(empty($default)) break;
$default = array_filter($default, function($val){return !empty($val);});
$value = "('" . implode("', '", $default) . "')";
$filterFormat[$field] = array('operator' => 'IN', 'value' => $value);
break;
case 'input':
$filterFormat[$field] = array('operator' => 'like', 'value' => "'%$default%'");
break;
case 'date':
case 'datetime':
$begin = $default['begin'];
$end = $default['end'];
if(empty($begin) or empty($end)) break;
$value = "'$begin' and '$end'";
$filterFormat[$field] = array('operator' => 'BETWEEN', 'value' => $value);
break;
case 'condition':
$operator = $filter['operator'];
$value = $filter['value'];
if(in_array($operator, array('IN', 'NOT IN')))
{
$valueArr = explode(',', $value);
foreach($valueArr as $key => $val) $valueArr[$key] = '"' . $val . '"';
$value = '(' . implode(',', $valueArr) . ')';
}
elseif(in_array($operator, array('IS NOT NULL', 'IS NULL')))
{
$value = '';
}
$filterFormat[$field] = array('operator' => $operator, 'value' => $value);
break;
}
}
$sql = str_replace(';', '', "$post->sql");
$fields = $post->fieldSettings;
$langs = isset($post->langs) ? $post->langs : array();
switch($type)
{
case 'line':
$data = $this->chart->genLineChart($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'cluBarX':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'cluBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'pie':
$data = $this->chart->genPie($fields, $settings, $sql, $filterFormat);
break;
case 'radar':
$data = $this->chart->genRadar($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'stackedBar':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
case 'stackedBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
}
echo json_encode($data);
}
}
+7
View File
@@ -0,0 +1,7 @@
.table-panel {overflow-x: auto;}
.datatable {width: auto;}
.datatable th.header {line-height: 32px !important;}
.header-config {float: right; display: none;}
.header:hover .header-config {display: inline-block;}
.label-outline.label-info {border: unset; line-height: 14px;}
.border-bottom {border-bottom: 1px solid #f4f5f7;}
+51
View File
@@ -0,0 +1,51 @@
.m-chart-preview {color: rgb(49, 60, 82); background-color: rgb(244, 245, 247);}
.main-col .btn-toolbar {margin-bottom: 10px;}
.main-position {position: relative;}
.child-position {position: absolute; right: 0;}
.parent-position{padding-right: 180px;}
#chartGroups li {overflow: hidden; white-space: nowrap;}
#chartGroups .checkbox-primary {margin-left: 8px; display: inline-block;}
#chartGroups .checkbox-primary + a {display: inline-block;}
#chartGroups .checkbox-primary > input[type=checkbox][name^=chart] + label {padding-left: 0px;}
.chart-item + .chart-item {margin-top: 10px;}
.chartbox {
height: 400px;
overflow: overlay;
border: 1px solid #ddd;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th {
padding: 8px!important;
}
.table-title {
top: 10px;
right: auto;
bottom: auto;
left: 10px;
width: auto;
height: auto;
margin: 0px 0px 10px 10px;
font-size: 18px;
font-weight: bold;
text-align: left;
}
#subNavbar .nav li.active a {display: none;}
#mainContent .cell {padding: 11px;}
#mainContent .panel {border: 0;}
#mainContent .chart-item.main-row x-vue-echarts {max-height: 460px;}
#mainContent .chart-item.main-row .ant-table-wrapper {max-height: 398px; overflow-y: overlay !important;border: 1px solid #e8e8e8; border-right: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table {border: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table tr:last-child td {border-bottom: 0;}
.echart-content {width: 100%; min-height: 500px;}
.filterBox{display: flex; margin-bottom: 20px;}
.filter-items{display: flex; flex: 1; flex-wrap: wrap;}
.filter-item{padding: 0 16px 5px 0;}
.filter-item-grow{flex-grow: 1;}
.queryBtn{display: flex; align-items: center; padding-bottom: 5px;}
.filterBox .picker-selections{width: 128px; height: 32px; overflow: hidden; text-overflow: clip; white-space: nowrap;}
+58
View File
@@ -0,0 +1,58 @@
var filterValues = {};
/**
* Ajax get chart data.
*
* @access public
* @return bool
*/
function ajaxGetChart(check = true, chart = DataStorage.chart, echart = window.echart)
{
var chartParams = JSON.parse(JSON.stringify(chart));
if(typeof DataStorage != 'undefined') chartParams.fieldSettings = JSON.parse(JSON.stringify(DataStorage.fieldSettings));
if(typeof DataStorage != 'undefined') chartParams.langs = JSON.parse(JSON.stringify(DataStorage.langs));
/* Redraw echart. */
/* 拿数据并重绘图表。*/
$.post(createLink('chart', 'ajaxGetChart'), chartParams, function(resp)
{
var data = JSON.parse(resp);
if(echart)
{
echart.clear();
echart.setOption(data, true);
$('.btn-export').removeClass('hidden');
}
});
}
/**
* Init picker.
*
* @access public
* @return void
*/
function initPicker($row, pickerName = 'picker-select')
{
$row.find('.' + pickerName).picker({'maxDropHeight': pickerHeight});
$row.find("." + pickerName).each(function(index)
{
if($(this).hasClass('required')) $(this).siblings("div .picker").addClass('required');
});
}
/**
* Init datepicker.
*
* @param object $obj
* @param function callback
* @access public
* @return void
*/
function initDatepicker($obj, callback)
{
$obj.find('.form-date').datepicker();
$obj.find('.form-datetime').datetimepicker();
if(typeof callback == 'function') callback($obj);
}
+215
View File
@@ -0,0 +1,215 @@
$(function()
{
initCheckBox();
initQueryBtn();
$('#exportchart').modalTrigger();
chartMap = new Map();
if(charts.length > 0)
{
charts.forEach(function(chart)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
ajaxGetChart(false, chart, echart);
renderFilters(chart);
chartMap.set(chart.currentGroup + chart.id, chart);
});
}
calcPreviewGrowFilter();
$('body').resize(() => {calcPreviewGrowFilter(true);});
$('[data-toggle="tooltip"]').tooltip();
})
/**
* Init check box.
*
* @access public
* @return void
*/
function initCheckBox()
{
/* Use parent checked prop set all child. */
$('input[data-type="parent"]').click(function()
{
$(this).parent().siblings('ul').find('input[data-type="child"]').prop('checked', $(this).prop('checked'));
});
$('input[data-type="child"]').click(function()
{
/* If child unchecked after click, set parent unchecked. */
if(!$(this).prop('checked'))
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', false);
}
/* If child checked after click, if all child checked, set parent checked. */
else
{
if($(this).closest('ul').find('input[data-type="child"]').length >= 1)
{
var siblings_checked = $(this).closest('ul').find('input[data-type="child"]:checked').length;
var siblings_total = $(this).closest('ul').find('input[data-type="child"]').length;
if(siblings_checked == siblings_total)
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', true);
}
}
}
});
/* Use click to trigger event. */
charts.forEach(function(item)
{
$("#chart_" + item.currentGroup + '_' + item.id).click();
});
}
/**
* Init query button.
*
* @access public
* @return void
*/
function initQueryBtn()
{
$('.btn-query').click(function()
{
var chartID = $(this).attr('data-chart');
var chartInfo = chartMap.get(chartID);
chartInfo.searchFilters = JSON.parse(JSON.stringify(chartInfo.filters));
// Foreach filters and set current value in searchFilters. */
$('#filterItems' + chartID + ' .filter-items').children().each(function(index)
{
var $child = $(this);
var filter = chartInfo.searchFilters[index];
var type = filter.type;
var value = null;
if(type == 'input' || type == 'select')
{
var value = $child.find('#default').val();
chartInfo.searchFilters[index].default = value;
}
else if(type == 'date' || type == 'datetime')
{
var begin = $child.find('input').first().val();
var end = $child.find('input').last().val();
var value = {"begin":begin, "end":end};
chartInfo.searchFilters[index].default = value;
}
else if(type == 'condition')
{
var operator = $child.find('#operator').data('zui.picker').getValue();
var value = $child.find('#value').val();
chartInfo.searchFilters[index].operator = operator;
chartInfo.searchFilters[index].value = value;
}
});
//* Reload echart. */
var echartDom = $('#chartDraw' + chartID).get(0);
var echartInfo = echarts.init(echartDom);
ajaxGetChart(false, chartInfo, echartInfo);
});
}
function calcPreviewGrowFilter(resize = false)
{
if(charts.length <= 0) return;
charts.forEach(function(chart)
{
/* When body resize, resize echarts. */
if(resize)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
echart.resize();
}
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
/* When refreshing this page, ZenTao load this page twice, when the first load isn't complete, jump back to index and load the second time,
the first load can't calc filter width, can't get the element using jQuery at first load. */
var hasInit = true;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var $titleSpan = $filterItems.find(nowItem).find('.input-group-addon').first();
if(!$titleSpan.length) hasInit = false;
});
if(!hasInit) return;
var domWidth = $filterItems[0].getBoundingClientRect().width;
var nowWidth = domWidth;
var nowCount = 0;
var canGrowTotal = 0;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var leftPadding = parseInt($filterItems.find(nowItem).css('padding-left'));
var rightPadding = parseInt($filterItems.find(nowItem).css('padding-right'));
var spanWidth = $filterItems.find(nowItem).find('.input-group-addon').first()[0].getBoundingClientRect().width;
var filterWidth = ((filter.type == 'input' || filter.type == 'select') ? WIDTH_INPUT : WIDTH_DATE) + (spanWidth + leftPadding + rightPadding);
/* Clear the flex-basis and set flex-basic again. */
$filterItems.find(nowItem).css('flex-basis', '');
$filterItems.find(nowItem).css('flex-basis', filterWidth);
if(nowWidth - filterWidth >= 0)
{
nowWidth -= filterWidth;
nowCount ++;
}
else
{
canGrowTotal += nowCount;
nowWidth = domWidth - filterWidth;
nowCount = 1;
}
});
/* Clear all filter filter-item-grow and add class to support grow element. */
$filterItems.children().removeClass('filter-item-grow');
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
if(canGrowTotal >= index + 1) $filterItems.find(nowItem).addClass('filter-item-grow');
});
});
}
function renderFilters(chart)
{
if(chart.filters.length == 0) return;
var fieldNames = {};
Object.keys(chart.fieldSettings).forEach(function(key){fieldNames[key] = chart.fieldSettings[key].name;});
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs}, function(resp)
{
resp = JSON.parse(resp);
chart.filters.forEach(function(filter, index)
{
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
$filterItems.append(renderFilterItem(filter, resp, index));
});
});
}
function renderFilterItem(filter, resp, index, step)
{
var tpl = $('#filterItemTpl').html();
var data =
{
index: index,
name: filter.name,
search: resp[index].item
};
var html = $($.zui.formatString(tpl, data))
initPicker(html);
initDatepicker(html);
return html;
}
+56
View File
@@ -0,0 +1,56 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
/* Cluster bar X graphs and cluster bar Y graphs are really just a switch between the x and y axes, so use a little ingenuity in the cluster bar Y language terms so that the methods can be reused.*/
/* 簇状柱形图和簇状条形图其实只是x轴和y轴换了换,所以在簇状条形图语言项上使用了点小聪明,这样方法就可以复用了。*/
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+34
View File
@@ -0,0 +1,34 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+56
View File
@@ -0,0 +1,56 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
/* Cluster bar X graphs and cluster bar Y graphs are really just a switch between the x and y axes, so use a little ingenuity in the cluster bar Y language terms so that the methods can be reused.*/
/* 簇状柱形图和簇状条形图其实只是x轴和y轴换了换,所以在簇状条形图语言项上使用了点小聪明,这样方法就可以复用了。*/
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+34
View File
@@ -0,0 +1,34 @@
<?php
$lang->chart->preview = '查看图表';
$lang->chart->query = '查询';
$lang->chart->toDesign = '进入设计';
$lang->chart->group = '所属分组';
$lang->chart->field = '关联字段';
$lang->chart->agg = '汇总';
$lang->chart->chooseField = '选择字段';
$lang->chart->aggType = '统计方式';
$lang->chart->other = '其他';
$lang->chart->unlimited = '不限';
$lang->chart->colon = '至';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = '文本框';
$lang->chart->fieldTypeList['date'] = '日期';
$lang->chart->fieldTypeList['datetime'] = '时间';
$lang->chart->fieldTypeList['select'] = '下拉菜单';
//$lang->chart->fieldTypeList['condition'] = '条件筛选';
$lang->chart->groupWeek = '%s年第%s周';
$lang->chart->noChart = '暂时没有图表';
$lang->chart->noChartSelected = '请选择至少一个图表。';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = '计数';
$lang->chart->aggList['distinct'] = '去重后计数';
$lang->chart->aggList['avg'] = '平均值';
$lang->chart->aggList['sum'] = '求和';
$lang->chart->aggList['max'] = '最大值';
$lang->chart->aggList['min'] = '最小值';
+633
View File
@@ -0,0 +1,633 @@
<?php
/**
* The model file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chartModel extends model
{
/**
* Get first chart group id.
*
* @param int $dimensionID
* @access public
* @return int
*/
public function getFirstChartGroupID($dimensionID)
{
return $this->dao->select('id')->from(TABLE_MODULE)
->where('deleted')->eq('0')
->andWhere('type')->eq('chart')
->andWhere('root')->eq($dimensionID)
->andWhere('grade')->eq(1)
->orderBy('`order`')
->limit(1)
->fetch('id');
}
/**
* Get chart.
*
* @param int $chartID
* @access public
* @return object
*/
public function getByID($chartID)
{
$chart = $this->dao->select('*')->from(TABLE_CHART)->where('id')->eq($chartID)->fetch();
if(!$chart) return false;
if(!empty($chart->fields) and $chart->fields != 'null')
{
$chart->fieldSettings = json_decode($chart->fields);
$chart->fields = array();
foreach($chart->fieldSettings as $field => $settings) $chart->fields[] = $field;
}
else
{
$chart->fieldSettings = array();
}
if($chart->sql == null) $chart->sql = '';
if(!empty($chart->filters)) $chart->filters = json_decode($chart->filters, true);
return $this->processChart($chart);
}
/**
* Process sql and correct type.
*
* @param object|array $charts
* @param bool $isObject
* @access public
* @return object|array
*/
public function processChart($charts, $isObject = true)
{
if($isObject) $charts = array($charts);
foreach($charts as $id => $chart)
{
if(!empty($chart->sql)) $charts[$id]->sql = trim(str_replace(';', '', $chart->sql));
if(!empty($chart->settings)) $charts[$id]->settings = json_decode($chart->settings, true);
if(!empty($chart->settings) and is_array($chart->settings))
{
$firstSetting = current($chart->settings);
if(isset($firstSetting['type'])) $charts[$id]->type = $firstSetting['type'];
}
}
return $isObject ? reset($charts) : $charts;
}
/**
* Get tree of charts and groups.
*
* @param int $groupID
* @param string $orderBy
* @access public
* @return array
*/
public function getPreviewCharts($groupID, $orderBy = 'id_desc')
{
if(!$groupID) return array('', array());
$currentGroup = $this->loadModel('tree')->getByID($groupID);
if(empty($currentGroup) || $currentGroup->grade != 1) return array('', array());
$groups = $this->dao->select('id, grade, name')->from(TABLE_MODULE)->where('deleted')->eq('0')->andWhere('path')->like("{$currentGroup->path}%")->orderBy('`order`')->fetchAll();
if(!$groups) return array('', array());
$chartGroups = array();
foreach($groups as $group)
{
$chartGroups[$group->id] = $this->dao->select('*')->from(TABLE_CHART)
->where('deleted')->eq(0)
->andWhere("FIND_IN_SET($group->id, `group`)")
->andWhere('stage')->ne('draft')
->orderBy($orderBy)
->fetchAll();
}
if(!$chartGroups) return array('', array());
$readyCharts = array();
foreach($chartGroups as $groupID => $chartGroup)
{
$charts = array();
foreach($chartGroup as $chart)
{
if($chart->stage != 'published') continue;
$charts[] = $chart;
}
if(!empty($charts)) $readyCharts[$groupID] = $charts;
}
$index = 1;
$chartTree = '';
$firstChart = null;
foreach($groups as $group)
{
if(!isset($readyCharts[$group->id])) continue;
if($group->grade == 2)
{
$class = $index == 1 ? 'open' : 'closed';
$chartTree .= "<li class='$class'><div class='checkbox-primary'><input type='checkbox' data-type='parent' name='groups[]' id='group{$group->id}' value='{$group->id}' title='{$group->name}'><label>{$group->name}</label></div><ul>";
}
$charts = $readyCharts[$group->id];
foreach($charts as $chart)
{
$chart->currentGroup = $group->id;
if(!$firstChart) $firstChart = $chart;
$chartTree .= "<li title='{$chart->name}'><div class='checkbox-primary checkbox-inline'><input type='checkbox' data-type='child' name='charts[]' id='chart_{$group->id}_{$chart->id}' value='{$group->id}_{$chart->id}' title='{$chart->name}' data-group='{$group->id}'><label for='chart_{$group->id}_{$chart->id}'></label></div><a>{$chart->name}</a></li>";
}
if($group->grade == 2) $chartTree .= '</ul></li>';
$index++;
}
if($chartTree) $chartTree = "<ul id='chartGroups' class='tree' data-ride='tree'>" . $chartTree . '</ul>';
$charts = array();
if($firstChart)
{
if(!empty($firstChart->settings)) $firstChart->settings = json_decode($firstChart->settings, true);
if(!empty($firstChart->filters)) $firstChart->filters = json_decode($firstChart->filters, true);
if(!empty($firstChart->fields) and $firstChart->fields != 'null')
{
$firstChart->fieldSettings = json_decode($firstChart->fields);
$firstChart->fields = array_keys(json_decode($firstChart->fields, true));
}
$charts[] = $firstChart;
}
return array($chartTree, $charts);
}
/**
* Gen radar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param array $langs
* @access public
* @return void
*/
public function genRadar($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
$max = 0;
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$yStatXLabel = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
$data[] = $yStatXLabel;
}
if(max($yStat) > $max) $max = max($yStat);
$yDatas[] = $data;
}
$series = array();
$legend = new stdclass();
$series['type'] = 'radar';
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series['data'][] = array('name' => $seriesName, 'value' => $yData);
}
$indicator = array();
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $xLabel)
{
$labelName = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$indicator[] = array('name' => $labelName, 'max' => $max);
}
$options = array('series' => $series, 'legend' => $legend, 'radar' => array('indicator' => $indicator), 'tooltip' => array('trigger' => 'item'));
return $options;
}
/**
* Gen pie.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @access public
* @return array
*/
public function genPie($fields, $settings, $sql, $filters)
{
$group = isset($settings['group'][0]['field']) ? $settings['group'][0]['field'] : '';
$date = isset($settings['group'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['group'][0]['group']) : '';
$metric = isset($settings['metric'][0]['field']) ? $settings['metric'][0]['field'] : '';
$agg = isset($settings['metric'][0]['valOrAgg']) ? $settings['metric'][0]['valOrAgg'] : '';
$defaultSql = str_replace(';', '', $sql);
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if(empty($date)) arsort($stat);
$copyStat = $stat;
$other = array_sum(array_splice($copyStat, $maxCount));
$stat[$this->lang->chart->other] = $other;
if(empty($date)) arsort($stat);
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
$data = array();
foreach($stat as $name => $value)
{
if($value == 0) continue;
$value = round($value, 2);
$labelName = isset($optionList[$name]) ? $optionList[$name] : $name;
$data[] = array('name' => $labelName, 'value' => $value);
}
$label = array('show' => true, 'position' => 'outside', 'formatter' => '{b} {d}%');
$legend = new stdclass();
$legend->type = 'scroll';
$legend->orient = 'vertical';
$legend->right = 0;
$series[] = array('data' => $data, 'type' => 'pie', 'label' => $label);
$options = array('series' => $series, 'legend' => $legend, 'tooltip' => array('trigger' => 'item', 'formatter' => "{b}<br/> {c} ({d}%)"));
return $options;
}
/**
* Process rows.
*
* @param array $rows
* @param string $date
* @param string $group
* @param string $metric
* @access public
* @return array
*/
public function processRows($rows, $date, $group, $metric)
{
$stat = array();
foreach($rows as $row)
{
if(!empty($date) and $date == 'MONTH')
{
$stat[sprintf("%04d", $row->ttyear) . '-' . sprintf("%02d", $row->ttgroup)] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEARWEEK')
{
$yearweek = sprintf("%06d", $row->$group);
$year = substr($yearweek, 0, strlen($yearweek) - 2);
$week = substr($yearweek, -2);
$weekIndex = in_array($this->app->getClientLang(), array('zh-cn', 'zh-tw')) ? sprintf($this->lang->chart->groupWeek, $year, $week) : sprintf($this->lang->chart->groupWeek, $week, $year);
$stat[$weekIndex] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEAR')
{
$stat[sprintf("%04d", $row->$group)] = $row->$metric;
}
else
{
$stat[$row->$group] = $row->$metric;
}
}
return $stat;
}
/**
* Gen line.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @param array $langs
* @access public
* @return array
*/
public function genLineChart($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$fieldType = $fields[$settings['xaxis'][0]['field']]['type'];
if($fieldType == 'date') sort($xLabels);
$yDatas = array();
foreach($xLabels as $xLabel)
{
foreach($yStats as $index => $yStat)
{
if(!isset($yDatas[$index])) $yDatas[$index] = array();
$yDatas[$index][] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels);
$yaxis = array('type' => 'value');
$legend = new stdclass();
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'line');
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Gen cluBar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param int $stack
* @param array $langs
* @access public
* @return void
*/
public function genCluBar($fields, $settings, $defaultSql, $filters, $stack = '', $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$data[] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
$yDatas[] = $data;
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels, 'axisLabel' => array('interval' => 0));
$yaxis = array('type' => 'value');
$legend = new stdclass();
/* Cluster bar X graphs and cluster bar Y graphs are really just x and y axes switched, so cluster bar Y $xaixs and $yaxis are swapped so that the method can be reused. */
/* 簇状柱形图和簇状条形图其实只是x轴和y轴换了换,所以交换一下簇状条形图 xAxis和yAxis即可,这样方法就可以复用了。*/
if(in_array($settings['type'], array('cluBarY', 'stackedBarY'))) list($xaxis, $yaxis) = array($yaxis, $xaxis);
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'bar', 'stack' => $stack);
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Get multi data.
*
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @access public
* @return void
*/
public function getMultiData($settings, $defaultSql, $filters, $sort = false)
{
$group = isset($settings['xaxis'][0]['field']) ? $settings['xaxis'][0]['field'] : '';
$date = isset($settings['xaxis'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['xaxis'][0]['group']) : '';
$metrics = array();
$aggs = array();
foreach($settings['yaxis'] as $yaxis)
{
$metrics[] = $yaxis['field'];
$aggs[] = $yaxis['valOrAgg'];
}
$yCount = count($metrics);
$xLabels = array();
$yStats = array();
for($i = 0; $i < $yCount; $i ++)
{
$metric = $metrics[$i];
$agg = $aggs[$i];
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if($sort) arsort($stat);
$yStats[] = $stat;
$xLabels = array_merge($xLabels, array_keys($stat));
$xLabels = array_unique($xLabels);
}
return array($group, $metrics, $aggs, $xLabels, $yStats);
}
/**
* Adjust the action is clickable.
*
* @param object $chart
* @param string $action
* @static
* @access public
* @return bool
*/
public static function isClickable($chart, $action)
{
return true;
}
/**
* Get sys options.
*
* @param string $type
* @access public
* @return array
*/
public function getSysOptions($type, $object = '', $field = '')
{
$options = array('' => '');
switch($type)
{
case 'user':
$options = $this->loadModel('user')->getPairs();
break;
case 'product':
$options = $this->loadModel('product')->getPairs();
break;
case 'project':
$options = $this->loadModel('project')->getPairsByProgram();
break;
case 'execution':
$options = $this->loadModel('execution')->getPairs();
break;
case 'dept':
$options = $this->loadModel('dept')->getOptionMenu(0);
break;
case 'option':
if($field)
{
$path = $this->app->getModuleRoot() . 'dataview' . DS . 'table' . DS . "$object.php";
include $path;
$options = $schema->fields[$field]['options'];
}
break;
case 'object':
if($field)
{
$table = zget($this->config->objectTables, $object);
$options = $this->dao->select("id, {$field}")->from($table)->fetchPairs();
}
break;
/*case 'string':
if($field)
{
$table = zget($this->config->objectTables, $object);
$options = $this->dao->select("{$field}, {$field}")->from($table)->fetchPairs();
}
break;
*/
}
return $options;
}
}
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* The preview view file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Gang Liu <liugang@easycorp.ltd>
* @package chart
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::import($jsRoot . 'moment/moment.min.js');?>
<?php js::import($jsRoot . 'echarts/echarts.common.min.js');?>
<?php js::set('groupID', isset($group->id) ? $group->id : 0);?>
<?php js::set('charts', $charts);?>
<?php js::set('noChartSelected', $lang->chart->noChartSelected);?>
<?php js::set('chartLang', $lang->chart);?>
<?php js::set('WIDTH_INPUT', $config->chart->widthInput);?>
<?php js::set('WIDTH_DATE', $config->chart->widthDate);?>
<?php js::set('pickerHeight', $config->bi->pickerHeight);?>
<div id='mainMenu' class='clearfix main-position'>
<div class='btn-toolBar pull-left parent-position'>
<?php
foreach($groups as $groupID => $groupName)
{
if(!$groupID) continue;
$activeClass = $groupID == $group->id ? 'btn-active-text' : '';
echo html::a(inlink('preview', "dimensionID={$dimensionID}&groupID={$groupID}"), $groupName, '', "class='btn btn-link {$activeClass}' id='{$groupID}Tab'");
}
?>
</div>
<?php if($this->config->edition == 'biz' or $this->config->edition == 'max'):?>
<div class='btn-toolbar pull-right child-position'>
<?php common::printLink('chart', 'exportChart', '', "<i class='icon icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link btn-export' id='exportchart'");?>
<?php common::printLink('chart', 'browse', '', $lang->chart->toDesign, '', "class='btn btn-primary '");?>
</div>
<?php endif;?>
</div>
<div id="mainContent" class='main-row'>
<div class='side-col col-lg'>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo isset($group->name) ? $group->name : '';?></div>
</div>
<div class='panel-body'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php elseif($chartTree):?>
<form method='post'>
<?php echo $chartTree;?>
<div class='btn-toolbar'>
<?php echo html::selectAll();?>
<?php echo html::submitButton($lang->chart->preview, '', 'btn btn-primary');?>
</div>
</form>
<?php endif;?>
</div>
</div>
</div>
<div class='main-col'>
<div class='cell'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php else:?>
<div class='btn-toolbar pull-right'>
</div>
<?php foreach($charts as $chart):?>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'>
<?php echo $chart->name;?>
<?php if(!empty($chart->desc)):?>
<a data-toggle='tooltip' data-placement='auto' title=<?php echo $chart->desc;?>><i class='icon-help'></i></a>
<?php endif;?>
</div>
</div>
<div class='panel-body'>
<div id="filterItems<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" class='filterBox'>
<div class='filter-items'></div>
<?php if(!empty($chart->filters)):?>
<div class='queryBtn'><?php echo html::submitButton($lang->chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?></div>
<?php endif;?>
</div>
<div id="chartDraw<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" data-group="<?php echo $chart->currentGroup;?>" data-id="<?php echo $chart->id;?>" class='echart-content'></div>
</div>
</div>
<?php endforeach;?>
<?php endif;?>
</div>
</div>
</div>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>
<template id='filterItemTpl'>
<div class='filter-item filter-item-{index}'>
<div class='input-group'>
<span class='input-group-addon field-name'>{name}</span>
{search}
</div>
</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = '编号';
$lang->dataview->name = '名称';
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['story'] = 'zt_story';
$schema->tables['productline'] = 'zt_module';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['bugmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['story'] = 'story.id = bug.story';
$schema->joins['productline'] = 'productline.id = product.line';
$schema->joins['program'] = 'program.id = product.program';
$schema->joins['project'] = 'project.id = bug.project';
$schema->joins['bugmodule'] = 'bugmodule.id = bug.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['bugmodule'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'bugmodule', 'show' => 'bugmodule.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->story->common, 'object' => 'story', 'show' => 'story.title');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'date', 'name' => $this->lang->bug->resolvedDate);
$schema->objects = array();
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->common);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['bugmodule'] = array();
$schema->objects['bugmodule']['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->objects['bugmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
+92
View File
@@ -0,0 +1,92 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('testtask');
$this->app->loadLang('build');
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['testcase'] = 'zt_case';
$schema->tables['build'] = 'zt_build';
$schema->tables['execution'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['module'] = 'zt_module';
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['testtask'] = 'testtask.id = bug.testtask';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['module'] = 'module.id = bug.module';
$schema->joins['testcase'] = 'testcase.id = bug.case';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['module'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'module', 'show' => 'module.name');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->resolvedDate);
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['module'] = array();
$schema->objects['module']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['module']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
+45
View File
@@ -0,0 +1,45 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'build';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'product.id = build.product';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->build->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->build->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->build->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->fields['builder'] = array('type' => 'user', 'name' => $this->lang->build->builder);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->build->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->build->bugs);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->build->date);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->build->desc);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+18
View File
@@ -0,0 +1,18 @@
<?php
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'casemodule';
$schema->tables = array();
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects = array();
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('testcase');
$casestepLang = new stdclass();
$casestepLang->type = '步骤类型';
$casestepLang->typeList['step'] = '步骤';
$casestepLang->typeList['group'] = '分组';
$schema = new stdclass();
$schema->primaryTable = 'casestep';
$schema->tables = array();
$schema->tables['casestep'] = 'zt_casestep';
$schema->tables['testcase'] = 'zt_case';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = casestep.`case`';
$schema->fields = array();
$schema->fields['case'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['type'] = array('type' => 'option', 'name' => $casestepLang->type, 'options' => $casestepLang->typeList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->testcase->desc);
$schema->fields['expect'] = array('type' => 'string', 'name' => $this->lang->testcase->expect);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
+37
View File
@@ -0,0 +1,37 @@
<?php
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'execution';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->joins = array();
$schema->joins['project'] = 'execution.project = project.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->name, 'object' => 'project', 'show' => 'project.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->execution->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->execution->type, 'options' => $this->lang->execution->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->execution->status, 'options' => $this->lang->execution->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->execution->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->execution->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->execution->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->execution->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->execution->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->execution->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->execution->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->execution->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
+41
View File
@@ -0,0 +1,41 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('program');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'product';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['program'] = 'zt_project';
$schema->tables['line'] = 'zt_module';
$schema->joins = array();
$schema->joins['program'] = 'product.program = program.id';
$schema->joins['line'] = 'product.line = line.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->fields['program'] = array('type' => 'object', 'name' => $this->lang->product->program, 'object' => 'program', 'show' => 'program.name');
$schema->fields['line'] = array('type' => 'object', 'name' => $this->lang->product->line, 'object' => 'line', 'show' => 'line.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->product->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->product->type, 'options' => $this->lang->product->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->product->status, 'options' => $this->lang->product->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->product->desc);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->product->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->product->RD);
$schema->fields['createdBy'] = array('type' => 'user', 'name' => $this->lang->product->createdBy);
$schema->fields['createdDate'] = array('type' => 'date', 'name' => $this->lang->product->createdDate);
$schema->objects = array();
$schema->objects['program'] = array();
$schema->objects['program']['id'] = array('type' => 'number', 'name' => $this->lang->program->id);
$schema->objects['program']['name'] = array('type' => 'string', 'name' => $this->lang->program->name);
$schema->objects['line'] = array();
$schema->objects['line']['name'] = array('type' => 'string', 'name' => $this->lang->product->line);
+28
View File
@@ -0,0 +1,28 @@
<?php
$this->app->loadLang('productplan');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'productplan';
$schema->tables = array();
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['product'] = 'productplan.product = product.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->productplan->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->productplan->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->productplan->status, 'options' => $this->lang->productplan->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->productplan->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->productplan->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->productplan->end);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'project';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->joins = array();
$schema->fields = array();
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->project->code);
$schema->fields['model'] = array('type' => 'option', 'name' => $this->lang->project->model, 'options' => $this->lang->project->modelList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->project->type, 'options' => $this->lang->project->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->project->status, 'options' => $this->lang->project->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->project->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->project->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->project->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->project->common . $this->lang->project->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->project->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->project->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->project->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->project->openedDate);
$schema->objects = array();
+46
View File
@@ -0,0 +1,46 @@
<?php
$this->app->loadLang('release');
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'release';
$schema->tables = array();
$schema->tables['release'] = 'zt_release';
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'release.product = product.id';
$schema->joins['project'] = 'release.project = project.id';
$schema->joins['build'] = 'release.build = build.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->release->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->release->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->release->build, 'object' => 'build', 'show' => 'build.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->release->name);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->release->status, 'options' => $this->lang->release->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->release->desc);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->release->date);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->release->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->release->bugs);
$schema->fields['leftBugs'] = array('type' => 'string', 'name' => $this->lang->release->leftBugs);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
+49
View File
@@ -0,0 +1,49 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('productplan');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'story';
$schema->tables = array();
$schema->tables['story'] = 'zt_story';
$schema->tables['product'] = 'zt_product';
$schema->tables['productline'] = 'zt_module';
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['storymodule'] = 'zt_module';
$schema->tables['storyspec'] = 'zt_storyspec';
$schema->joins = array();
$schema->joins['product'] = 'product.id = story.product';
$schema->joins['storymodule'] = 'storymodule.id = story.module';
$schema->joins['storyspec'] = 'storyspec.story = story.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->story->status, 'options' => $this->lang->story->statusList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->story->stage, 'options' => $this->lang->story->stageList);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->story->pri, 'options' => $this->lang->story->priList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->story->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['storymodule'] = array('type' => 'object', 'name' => $this->lang->story->module, 'object' => 'storymodule', 'show' => 'storymodule.name');
$schema->fields['closedDate'] = array('type' => 'date', 'name' => $this->lang->story->closedDate);
$schema->fields['closedReason'] = array('type' => 'option', 'name' => $this->lang->story->closedReason, 'options' => $this->lang->story->reasonList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->story->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->story->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['storymodule'] = array();
$schema->objects['storymodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['storymodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('story');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'task';
$schema->tables = array();
$schema->tables['task'] = 'zt_task';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['story'] = 'zt_story';
$schema->tables['taskmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['execution'] = 'task.execution = execution.id';
$schema->joins['project'] = 'task.project = project.id';
$schema->joins['story'] = 'task.story = story.id';
$schema->joins['taskmodule'] = 'task.module = taskmodule.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->task->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->task->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->task->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['taskmodule'] = array('type' => 'object', 'name' => $this->lang->task->module, 'object' => 'taskmodule', 'show' => 'taskmodule.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->task->name);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->task->pri, 'options' => $this->lang->task->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->task->type, 'options' => $this->lang->task->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->task->status, 'options' => $this->lang->task->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->task->desc);
$schema->fields['estimate'] = array('type' => 'string', 'name' => $this->lang->task->estimate);
$schema->fields['consumed'] = array('type' => 'string', 'name' => $this->lang->task->consumed);
$schema->fields['left'] = array('type' => 'string', 'name' => $this->lang->task->left);
$schema->fields['estStarted'] = array('type' => 'date', 'name' => $this->lang->task->estStarted);
$schema->fields['deadline'] = array('type' => 'date', 'name' => $this->lang->task->deadline);
$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->task->assignedTo);
$schema->fields['finishedBy'] = array('type' => 'user', 'name' => $this->lang->task->finishedBy);
$schema->fields['closedBy'] = array('type' => 'user', 'name' => $this->lang->task->closedBy);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->task->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->task->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->objects['taskmodule'] = array();
$schema->objects['taskmodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['taskmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+36
View File
@@ -0,0 +1,36 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$teamLang = new stdclass();
$teamLang->type = '对象类型';
$teamLang->typeList['task'] = '任务';
$teamLang->typeList['execution'] = '执行';
$teamLang->typeList['project'] = '项目';
$schema = new stdclass();
$schema->primaryTable = 'team';
$schema->tables = array();
$schema->tables['team'] = 'zt_team';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['task'] = 'zt_task';
$schema->joins = array();
$schema->joins['execution'] = 'team.root = execution.id';
$schema->joins['project'] = 'team.root = project.id';
$schema->joins['task'] = 'team.root = task.id';
$schema->fields = array();
$schema->fields['root'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['account'] = array('type' => 'user', 'name' => $this->lang->team->account);
$schema->fields['type'] = array('type' => 'option', 'name' => $teamLang->type, 'options' => $teamLang->typeList);
$schema->objects = array();
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+52
View File
@@ -0,0 +1,52 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('tree');
$this->app->loadLang('story');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testcase';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['product'] = 'zt_product';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['story'] = 'zt_story';
$schema->tables['casestep'] = 'zt_casestep';
$schema->joins = array();
$schema->joins['product'] = 'product.id = testcase.product';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['story'] = 'story.id = testcase.story';
$schema->joins['casestep'] = 'casestep.case = testcase.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testcase->pri, 'options' => $this->lang->testcase->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testcase->type, 'options' => $this->lang->testcase->typeList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->testcase->stage, 'options' => $this->lang->testcase->stageList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testcase->status, 'options' => $this->lang->testcase->statusList);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testcase->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->testcase->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->testcase->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->testcase->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->testcase->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
+84
View File
@@ -0,0 +1,84 @@
<?php
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('tree');
$this->app->loadLang('build');
$this->app->loadLang('caselib');
$this->app->loadLang('product');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testresult';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['testrun'] = 'zt_testrun';
$schema->tables['testresult'] = 'zt_testresult';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['build'] = 'zt_build';
$schema->tables['caselib'] = 'zt_testsuite';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = testresult.case';
$schema->joins['testrun'] = 'testrun.id = testresult.run';
$schema->joins['testtask'] = 'testrun.task = testtask.id';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['caselib'] = 'caselib.id = testcase.lib';
$schema->joins['product'] = 'product.id = testcase.product';
$schema->fields = array();
$schema->fields['caseResult'] = array('type' => 'option', 'name' => $this->lang->testtask->caseResult, 'options' => $this->lang->testcase->resultList);
$schema->fields['stepResults'] = array('type' => 'json', 'name' => $this->lang->testtask->stepResults);
$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->testtask->date);
$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['caselib'] = array('type' => 'object', 'name' => $this->lang->caselib->common, 'object' => 'caselib', 'show' => 'caselib.name');
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
$schema->objects['caselib'] = array();
$schema->objects['caselib']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['caselib']['name'] = array('type' => 'string', 'name' => $this->lang->caselib->name);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+78
View File
@@ -0,0 +1,78 @@
<?php
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('tree');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$this->app->loadLang('product');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testrun';
$schema->tables = array();
$schema->tables['testrun'] = 'zt_testrun';
$schema->tables['testcase'] = 'zt_case';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = testrun.case';
$schema->joins['product'] = 'product.id = testcase.product';
$schema->joins['testtask'] = 'testtask.id = testrun.task';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->fields = array();
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->testcase->assignedTo);
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner);
$schema->fields['lastRunDate'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunDate);
$schema->fields['lastRunResult'] = array('type' => 'option', 'name' => $this->lang->testtask->lastRunResult, 'options' => $this->lang->testcase->resultList);
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+56
View File
@@ -0,0 +1,56 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$this->app->loadLang('testtask');
$schema = new stdclass();
$schema->primaryTable = 'testtask';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->tables['testtask'] = 'zt_testtask';
$schema->joins = array();
$schema->joins['product'] = 'product.id = testtask.product';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testtask->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->testtask->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->testtask->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->testtask->build, 'object' => 'build', 'show' => 'build.name');
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testtask->type, 'options' => $this->lang->testtask->typeList);
$schema->fields['owner'] = array('type' => 'user', 'name' => $this->lang->testtask->owner);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testtask->pri, 'options' => $this->lang->testtask->priList);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->testtask->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->testtask->end);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testtask->status, 'options' => $this->lang->testtask->statusList);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);