diff --git a/module/block/control.php b/module/block/control.php index 0168c3a7f8..3bb43b0046 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -528,7 +528,7 @@ class block extends control { $this->app->loadLang('build'); $projects = $this->loadModel('project')->getPairs(); - $this->view->builds = $this->dao->select('t1.*,t2.productName')->from(TABLE_BUILD)->alias('t1') + $this->view->builds = $this->dao->select('t1.*, t2.name as productName')->from(TABLE_BUILD)->alias('t1') ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id') ->where('t1.deleted')->eq('0') ->andWhere('t1.project')->in(array_keys($projects)) diff --git a/module/block/js/dashboard.js b/module/block/js/dashboard.js index 40f127ade1..b03c30b1c6 100644 --- a/module/block/js/dashboard.js +++ b/module/block/js/dashboard.js @@ -51,6 +51,12 @@ function checkEmpty() $dashboard.find('.dashboard-empty-message').toggleClass('hide', hasBlocks); } +/** + * Resize block + * @param object $event + * @access public + * @return void + */ function resizeBlock(event) { var blockID = event.element.find('.panel').data('id'); @@ -60,6 +66,33 @@ function resizeBlock(event) }); } +/** + * Init table header + * @access public + * @return void + */ +function initTableHeader() +{ + $('#dashboard .panel-block').each(function() + { + var $panel = $(this); + var $table = $panel.find('.table:first'); + + console.log($table.length, $table.children('thead').length, this); + if(!$table.length || !$table.children('thead').length) return; + console.log('ok'); + + var $header = $panel.children('.table-header-fixed'); + if(!$header.length) + { + $header = $('
').css('right', $panel.width() - $table.width() - 2); + $header.find('.table').append($table.find('thead').clone()); + $panel.addClass('with-fixed-header').append($header); + var $heading = $panel.children('.panel-heading'); + if($heading.length) $header.css('top', $heading.outerHeight()); + } + }); +} $(function() { @@ -73,12 +106,14 @@ $(function() sensitive : true, panelRemovingTip : config.confirmRemoveBlock, resizable : true, - onResize : resizeBlock + onResize : resizeBlock, + afterRefresh : initTableHeader }); $dashboard.find('ul.dashboard-actions').addClass('hide').children('li').addClass('right').appendTo($('#modulemenu > .nav')); $dashboard.find('[data-toggle=tooltip]').tooltip({container: 'body'}); checkEmpty(); + initTableHeader(); }); diff --git a/module/block/view/dashboard.html.php b/module/block/view/dashboard.html.php index 96037750a9..e68ffe1f0d 100644 --- a/module/block/view/dashboard.html.php +++ b/module/block/view/dashboard.html.php @@ -15,6 +15,7 @@ $jsRoot = $webRoot . "js/"; $themeRoot = $webRoot . "theme/"; if(isset($pageCSS)) css::internal($pageCSS); ?> +
diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index 910b33990e..33397c7b7e 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -90,6 +90,7 @@ $lang->bug->saveTemplate = 'Save template'; $lang->bug->deleteTemplate = 'Delete template'; $lang->bug->confirmStoryChange = 'Confirm Story Change'; $lang->bug->setPublic = 'Set public template'; +$lang->bug->batchChangeModule = 'Batch change module'; /* Browse tabs. */ $lang->bug->assignToMe = 'MyBugs'; diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 5b85c4ae5a..7e480f403f 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -90,6 +90,7 @@ $lang->bug->deleteTemplate = '删除模板'; $lang->bug->confirmStoryChange = '确认需求变动'; $lang->bug->setPublic = '设为公共模板'; $lang->bug->colorTag = '颜色标签'; +$lang->bug->batchChangeModule = '批量修改模块'; /* 查询条件列表。*/ $lang->bug->assignToMe = '指派给我'; diff --git a/module/common/view/datatable.fix.html.php b/module/common/view/datatable.fix.html.php index e0f64b24c9..d06dfb167d 100644 --- a/module/common/view/datatable.fix.html.php +++ b/module/common/view/datatable.fix.html.php @@ -1,7 +1,7 @@ moduleName . $this->methodName;?> diff --git a/module/common/view/datatable.html.php b/module/common/view/datatable.html.php index ec5c1faf9b..22437a4526 100644 --- a/module/common/view/datatable.html.php +++ b/module/common/view/datatable.html.php @@ -1,11 +1,4 @@ getExtViewFile(__FILE__)){include $extView; return helper::cd();}?> -debug) -{ - css::import($jsRoot . 'datatable/min.css'); - js::import($jsRoot . 'datatable/min.js'); -} -?> datatable)):?>
diff --git a/module/testtask/view/runcase.html.php b/module/testtask/view/runcase.html.php index 4ec25c4875..06f4e7908b 100644 --- a/module/testtask/view/runcase.html.php +++ b/module/testtask/view/runcase.html.php @@ -19,18 +19,23 @@
-
+ - + - + case->steps as $key => $step):?> @@ -40,7 +45,14 @@ - + @@ -64,6 +76,46 @@
testcase->precondition;?> case->precondition;?>
testcase->stepID;?> testcase->stepDesc;?> testcase->stepExpect;?> testcase->result;?>testcase->real;?> + testcase->real;?> + case->steps)):?> + + +
desc);?> expect);?> id]", $lang->testcase->resultList, $defaultResult, "class='form-control'");?>id]", '', "rows=2 class='form-control'");?> + + + + + +
id]", '', "rows=2 class='form-control fix-textarea'");?>
+
+ case->steps)):?> + + + case->steps as $key => $step):?> + id}", "labels{$step->id}");?> + + +
diff --git a/module/upgrade/model.php b/module/upgrade/model.php index 6b8107eaed..67b3b95f44 100644 --- a/module/upgrade/model.php +++ b/module/upgrade/model.php @@ -136,6 +136,9 @@ class upgradeModel extends model $this->addPriv8_1(); case '8_1': $this->execSQL($this->getUpgradeFile('8.1')); + case '8_1_3': + $this->execSQL($this->getUpgradeFile('8.1.3')); + $this->addPriv8_2(); default: if(!$this->isError()) $this->setting->updateVersion($this->config->version); } @@ -861,6 +864,42 @@ class upgradeModel extends model $this->dao->replace($privTable)->set('module')->eq('project')->set('method')->eq('kanban')->set('`group`')->eq($group)->exec(); } + $groups = $this->dao->select('`group`')->from($privTable)->where('`module`')->eq('user')->andWhere('`method`')->eq('manageContacts')->fetchPairs('group', 'group'); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('my')->set('method')->eq('manageContacts')->set('`group`')->eq($group)->exec(); + } + + $groups = $this->dao->select('`group`')->from($privTable)->where('`module`')->eq('user')->andWhere('`method`')->eq('deleteContacts')->fetchPairs('group', 'group'); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('my')->set('method')->eq('deleteContacts')->set('`group`')->eq($group)->exec(); + } + + $groups = $this->dao->select('*')->from($privTable)->where('module')->eq('story')->andWhere('method')->eq('edit')->fetchAll(); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('story')->set('method')->eq('batchChangeModule')->set('`group`')->eq($group)->exec(); + } + + $groups = $this->dao->select('*')->from($privTable)->where('module')->eq('bug')->andWhere('method')->eq('edit')->fetchAll(); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('bug')->set('method')->eq('batchChangeModule')->set('`group`')->eq($group)->exec(); + } + + $groups = $this->dao->select('*')->from($privTable)->where('module')->eq('task')->andWhere('method')->eq('edit')->fetchAll(); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('task')->set('method')->eq('batchChangeModule')->set('`group`')->eq($group)->exec(); + } + + $groups = $this->dao->select('*')->from($privTable)->where('module')->eq('testcase')->andWhere('method')->eq('edit')->fetchAll(); + foreach($groups as $group) + { + $this->dao->replace($privTable)->set('module')->eq('testcase')->set('method')->eq('batchChangeModule')->set('`group`')->eq($group)->exec(); + } + return true; } diff --git a/www/js/datatable/min.css b/www/js/datatable/min.css deleted file mode 100644 index 89b154b819..0000000000 --- a/www/js/datatable/min.css +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * ZUI - v1.3.2 - 2015-09-16 - * http://zui.sexy - * GitHub: https://github.com/easysoft/zui.git - * Copyright (c) 2015 cnezsoft.com; Licensed MIT - */.datatable-head,.datatable-rows{display:table;width:100%;table-layout:fixed}.datatable{margin-bottom:20px}.datatable>.datatable-head{-webkit-transition:-webkit-box-shadow .2s;-o-transition:box-shadow .2s;transition:box-shadow .2s}.datatable .table{margin:0;table-layout:fixed}.datatable .table>tbody>tr>td,.datatable .table>thead>tr>th{min-width:20px}.datatable .table>tbody>tr>td.check-btn,.datatable .table>thead>tr>th.check-btn{width:30px;color:#9b9b9b;text-align:center;cursor:pointer}.datatable .table>tbody>tr.hover>td.check-btn,.datatable .table>tbody>tr.active>td.check-btn,.datatable .table>thead>tr>th.check-btn:hover,.datatable .table>tbody>tr>td.check-btn:hover,.datatable .table>thead>tr>th.check-btn.checked,.datatable .table>tbody>tr>td.check-btn.checked{color:#4f4f4f}.datatable .table>thead>tr>th.check-btn.checked>.icon-check-empty:before,.datatable .table>tbody>tr>td.check-btn.checked>.icon-check-empty:before,.datatable .table>tbody>tr.active>td.check-btn>.icon-check-empty:before{content:'\e60d'}.datatable .table>thead>tr>th.col-hover{background-color:#e2e2e2}.datatable .table>tbody>tr>td.col-hover,.datatable .table>tbody>tr.hover>td{background-color:#ebf2f9}.datatable .table>tbody>tr.active.hover td{background-color:#ffdea2}.datatable.head-fixed>.datatable-head{position:fixed;z-index:10000;-webkit-box-shadow:0 1px 4px 0 rgba(0,0,0,.15);box-shadow:0 1px 4px 0 rgba(0,0,0,.15)}.datatable.sortable .datatable-head-span .table>thead>tr>th{overflow:hidden;white-space:nowrap;cursor:pointer}.datatable.sortable .datatable-head-span .table>thead>tr>th.text-center{padding-right:0;padding-left:0}.datatable.sortable .datatable-head-span .table>thead>tr>th:after{display:inline-block;margin-left:5px;font-family:ZenIcon;font-size:14px;font-style:normal;font-weight:400;font-variant:normal;line-height:1;color:gray;text-transform:none;content:'\e6bd';speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-down:after{color:#145ccd;content:'\e6b8'}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-up:after{color:#145ccd;content:'\e6b9'}.datatable.sortable .datatable-head-span .table>thead>tr>th.check-btn:after,.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled:after{display:none}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled{cursor:default}.datatable-wrapper{position:relative}.datatable-span{display:table-cell;vertical-align:top}.datatable-span.flexarea{overflow:hidden}.datatable-span.flexarea.datatable-head-span.dragging{cursor:move!important}.datatable-span.flexarea .table{position:relative;top:0;left:0}.datatable-span.flexarea .scrolled-shadow{position:absolute;top:0;bottom:0;display:none;width:20px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.15);box-shadow:0 0 10px rgba(0,0,0,.15);opacity:0;-webkit-transition:all .5s cubic-bezier(.175,.885,.32,1);-o-transition:all .5s cubic-bezier(.175,.885,.32,1);transition:all .5s cubic-bezier(.175,.885,.32,1)}.datatable-span.flexarea .scrolled-in-shadow{left:-30px}.datatable-span.flexarea .scrolled-out-shadow{right:-30px}.datatable>.scroll-wrapper{position:relative;width:100%}.datatable .scroll-slide{position:absolute;right:-1px;bottom:0;left:-1px;display:none;height:11px;background:#e5e5e5;background:rgba(128,128,128,.1);border:1px solid #e5e5e5;border-bottom:none;opacity:0;-webkit-transition:opacity .5s,background .3s;-o-transition:opacity .5s,background .3s;transition:opacity .5s,background .3s}.datatable .scroll-slide>.bar{position:absolute;top:0;left:0;min-width:50px;height:10px;cursor:move;background-color:#a6a6a6}.datatable .scroll-slide:hover>.bar{background-color:gray}.datatable .scroll-slide.scroll-pos-out{bottom:-14px;height:15px}.datatable .scroll-slide.scroll-pos-out>.bar{height:14px}.datatable.show-scroll-slide:hover .scroll-slide,.datatable.show-scroll-slide.scrolling .scroll-slide,.datatable.show-scroll-slide:hover .scrolled-shadow,.datatable.show-scroll-slide.scrolling .scrolled-shadow{opacity:1}.datatable.show-scroll-slide .scroll-slide,.datatable.show-scroll-slide .scrolled-shadow{display:block}.datatable.show-scroll-slide.scrolled-in .scrolled-in-shadow{left:-20px}.datatable.show-scroll-slide.scrolled-out .scrolled-out-shadow{right:-20px} \ No newline at end of file diff --git a/www/js/datatable/min.js b/www/js/datatable/min.js deleted file mode 100644 index db67e7586b..0000000000 --- a/www/js/datatable/min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * ZUI - v1.3.2 - 2015-07-28 - * http://zui.sexy - * GitHub: https://github.com/easysoft/zui.git - * Copyright (c) 2015 cnezsoft.com; Licensed MIT - */ - -!function(a){"use strict";var b="zui.datatable",c=(a.zui.store,function(c,d){this.name=b,this.$=a(c),this.isTable="TABLE"===this.$[0].tagName,this.firstShow=!0,this.isTable?(this.$table=this.$,this.id="datatable-"+(this.$.attr("id")||a.zui.uuid())):(this.$datatable=this.$.addClass("datatable"),this.$.attr("id")?this.id=this.$.attr("id"):(this.id="datatable-"+a.zui.uuid(),this.$.attr("id",this.id))),this.getOptions(d),this.load(),this.callEvent("ready")});c.DEFAULTS={checkable:!1,checkByClickRow:!0,checkedClass:"active",checkboxName:null,sortable:!1,storage:!0,fixedHeader:!0,fixedHeaderOffset:0,fixedLeftWidth:"30%",fixedRightWidth:"30%",flexHeadDrag:!0,scrollPos:"in",rowHover:!0,colHover:!0,hoverClass:"hover",colHoverClass:"col-hover",mergeRows:!1,minColWidth:20,minFixedLeftWidth:200,minFixedRightWidth:200,minFlexAreaWidth:200},c.prototype.getOptions=function(b){var d=this.$;b=a.extend({},c.DEFAULTS,this.$.data(),b),b.tableClass=b.tableClass||"",b.tableClass=" "+b.tableClass+" table-datatable",a.each(["bordered","condensed","striped","condensed","fixed"],function(a,c){c="table-"+c,d.hasClass(c)&&(b.tableClass+=" "+c)}),(d.hasClass("table-hover")||b.rowHover)&&(b.tableClass+=" table-hover"),this.options=b},c.prototype.load=function(c){var d,e=this.options;if(a.isPlainObject(c))this.data=c;else if("string"==typeof c){var f=a(c);f.length&&(this.$table=f.first(),this.$table.data(b,this),this.isTable=!0),c=null}else c=e.data;if(!c){if(!this.isTable)throw new Error("No data avaliable!");c={cols:[],rows:[]},d=c.cols;var g,h,i,j,k,l,m=c.rows,n=this.$table;n.find("thead > tr:first").children("th").each(function(){h=a(this),d.push(a.extend({text:h.html(),flex:!1||h.hasClass("flex-col"),width:"auto",cssClass:h.attr("class"),css:h.attr("style"),type:"string",ignore:h.hasClass("ignore"),sort:!h.hasClass("sort-disabled"),mergeRows:h.attr("merge-rows")},h.data()))}),n.find("tbody > tr").each(function(){i=a(this),k=a.extend({data:[],checked:!1,cssClass:i.attr("class"),css:i.attr("style"),id:i.attr("id")},i.data()),i.children("td").each(function(){if(j=a(this),l=j.attr("colspan")||1,k.data.push(a.extend({cssClass:j.attr("class"),css:j.attr("style"),text:j.html(),colSpan:l,title:j.attr("title")},j.data())),l>1)for(g=1;l>g;g++)k.data.push({empty:!0})}),m.push(k)});var o=n.find("tfoot");o.length&&(c.footer=a('
').append(o))}c.flexStart=-1,c.flexEnd=-1,d=c.cols,c.colsLength=d.length;for(var g=0;g=0,c.fixedRight=c.flexEnd>=0&&c.flexEnd0,c.flexStart<0&&c.flexEnd<0&&(c.fixedLeft=!0,c.flexStart=c.colsLength,c.flexEnd=c.colsLength),this.data=c,this.callEvent("afterLoad",{data:c}),this.render()},c.prototype.render=function(){var c,d,e,f,g=this,h=g.$datatable||(g.isTable?a('
'):g.$datatable),i=g.options,j=g.data,k=g.data.cols,l=g.data.rows,m=i.checkable,n='
',o='
';h.children(".datatable-head, .datatable-rows, .scroll-wrapper").remove(),h.toggleClass("sortable",i.sortable);var p,q,r,s=a('
');for(c=a(""),e=a(""),f=a(""),d=0;d=j.flexStart&&d<=j.flexEnd?f:e,0===d&&m&&p.append(''),r.ignore||(q=a(""),q.toggleClass("sort-down","down"===r.sort).toggleClass("sort-up","up"===r.sort).toggleClass("sort-disabled",r.sort===!1),q.addClass(r.cssClass).addClass(r.colClass).html(r.text).attr({"data-index":d,"data-type":r.type,style:r.css}),p.append(q));var t;j.fixedLeft&&(t=a(o),t.addClass("fixed-left").find("table").addClass(i.tableClass).find("thead").append(c),s.append(t)),j.flexArea&&(t=a(o),t.addClass("flexarea").find(".datatable-wrapper").append('
').find("table").addClass(i.tableClass).find("thead").append(f),s.append(t)),j.fixedRight&&(t=a(o),t.addClass("fixed-right").find("table").addClass(i.tableClass).find("thead").append(e),s.append(t)),h.append(s);var u,v,w,x,y,z,A,B,C=a('
'),D=l.length;c=a(""),e=a(""),f=a("");for(var E=0;D>E;++E){for(z=l[E],"undefined"==typeof z.id&&(z.id=E),z.index=E,u=a(""),u.addClass(z.cssClass).toggleClass(i.checkedClass,z.checked).attr({"data-index":E,"data-id":z.id}),v=u.clone(),w=u.clone(),B=z.data.length,d=0;B>d;++d)A=z.data[d],d>0&&A.empty||(p=d=j.flexStart&&d<=j.flexEnd?v:w,0===d&&m&&(y=a(''),i.checkboxName&&y.append(''),p.append(y)),k[d].ignore||(a.isPlainObject(A)?(A.row=E,A.index=d):A={text:A,row:E,index:d},z.data[d]=A,x=a(""),x.html(A.text).addClass(A.cssClass).addClass(k[d].colClass).attr("colspan",A.colSpan).attr({"data-row":E,"data-index":d,"data-flex":!1,"data-type":k[d].type,style:A.css,title:A.title||""}),p.append(x)));c.append(u),f.append(v),e.append(w)}var F;j.fixedLeft&&(F=a(n),F.addClass("fixed-left").find("table").addClass(i.tableClass).append(c),C.append(F)),j.flexArea&&(F=a(n),F.addClass("flexarea").find(".datatable-wrapper").append('
').find("table").addClass(i.tableClass).append(f),C.append(F)),j.fixedRight&&(F=a(n),F.addClass("fixed-right").find("table").addClass(i.tableClass).append(e),C.append(F)),h.append(C),j.flexArea&&h.append('
');var G=h.children(".datatable-footer").detach();j.footer?(h.append(a('