Merge branch 'sprint/247' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/247_wzm_72350

This commit is contained in:
tianshujie
2022-10-21 08:37:44 +08:00
47 changed files with 376 additions and 106 deletions
+4 -2
View File
@@ -138,6 +138,7 @@ $filter->svn->cat = new stdclass();
$filter->svn->diff = new stdclass();
$filter->task->create = new stdclass();
$filter->task->export = new stdclass();
$filter->task->recordestimate = new stdclass();
$filter->execution->default = new stdclass();
$filter->execution->story = new stdclass();
$filter->testcase->default = new stdclass();
@@ -298,8 +299,9 @@ $filter->story->track->cookie['preProductID'] = 'int';
$filter->productplan->browse->cookie['viewType'] = 'code';
$filter->task->create->cookie['lastTaskModule'] = 'int';
$filter->task->export->cookie['checkedItem'] = 'reg::checked';
$filter->task->create->cookie['lastTaskModule'] = 'int';
$filter->task->export->cookie['checkedItem'] = 'reg::checked';
$filter->task->recordestimate->cookie['taskEffortFold'] = 'reg::checked';
$filter->execution->default->cookie['kanbanview'] = 'code';
$filter->execution->story->cookie['storyPreExecutionID'] = 'int';
-1
View File
@@ -15,7 +15,6 @@ CREATE TABLE IF NOT EXISTS `zt_ticket` (
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
+1 -1
View File
@@ -6333,6 +6333,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`pinnedMessages` text NOT NULL DEFAULT '',
`mergedChats` text NOT NULL DEFAULT '',
`adminInvite` enum('0','1') NOT NULL DEFAULT '0',
`avatar` text NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `gid` (`gid`),
KEY `name` (`name`),
@@ -7141,7 +7142,6 @@ CREATE TABLE IF NOT EXISTS `zt_ticket` (
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`consumed` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
+1
View File
@@ -380,6 +380,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
+1
View File
@@ -380,6 +380,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
+1
View File
@@ -380,6 +380,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
+1
View File
@@ -380,6 +380,7 @@ $lang->action->label->importedproductplan = '导入了';
$lang->action->label->importedrelease = '导入了';
$lang->action->label->importedexecution = '导入了';
$lang->action->label->importedbuild = '导入了';
$lang->action->label->importedticket = '导入了';
$lang->action->label->fromsonarqube = '由SonarQube问题创建';
$lang->action->label->bind = '绑定了';
$lang->action->label->unbind = '取消绑定了';
+1 -1
View File
@@ -1264,7 +1264,7 @@ class actionModel extends model
{
$objectType = str_replace('imported', '', $action->action);
$objectTable = zget($this->config->objectTables, $objectType);
$objectName = $objectType == 'productplan' ? 'title' : 'name';
$objectName = ($objectType == 'productplan' or $objectType == 'ticket') ? 'title' : 'name';
$action->objectName = $this->dao->select($objectName)->from($objectTable)->where('id')->eq($action->extra)->fetch($objectName);
}
elseif($action->objectType == 'module' and !empty($action->extra) and $action->action != 'deleted')
+1 -1
View File
@@ -4630,7 +4630,7 @@ class executionModel extends model
}
else
{
echo $execution->name;
echo "<span class='text-ellipsis'>" . $execution->name . '</span>';
if(!helper::isZeroDate($execution->end))
{
if($execution->status != 'closed')
+1 -1
View File
@@ -157,7 +157,7 @@ js::set('priv',
</div>
</div>
<?php
$width = common::checkNotCN() ? '600px' : '470px';
$width = common::checkNotCN() ? '600px' : '520px';
echo html::a('javascript:toggleRDSearchBox()', "<i class='icon-search muted'></i> " . $lang->searchAB, '', "class='btn btn-link querybox-toggle'");
echo html::a('javascript:fullScreen()', "<i class='icon-fullscreen muted'></i> " . $lang->kanban->fullScreen, '', "class='btn btn-link'");
if(common::hasPriv('execution', 'setKanban')) echo html::a(helper::createLink('execution', 'setKanban', "executionID=$execution->id", '', true), '<i class="icon icon-cog-outline"></i> ' . $lang->settings, '', "class='iframe btn btn-link text-left' data-width='$width'");
+1
View File
@@ -8,3 +8,4 @@
#mainContent .objectBox .checkbox-primary>label:after {width: 14px; height: 14px;}
#mainContent table > tbody th {width: 110px !important;}
[lang^=en] .laneHeightBox > label, [lang^=de] .laneHeightBox > label, [lang^=fr] .laneHeightBox > label, [lang^=en] .importBox > label, [lang^=de] .importBox > label, [lang^=fr] .importBox > label {margin-left: 0px;}
#dataform tr > th {vertical-align: top;}
+12 -1
View File
@@ -62,6 +62,7 @@ $app->loadLang('execution');
$app->loadLang('release');
$app->loadLang('build');
$app->loadLang('productplan');
if($this->config->edition != 'open') $app->loadLang('ticket');
js::set('systemMode', $this->config->systemMode);
?>
<div class='panel'>
@@ -103,7 +104,12 @@ js::set('systemMode', $this->config->systemMode);
<?php else:?>
<?php
$name = isset($card->title) ? $card->title : $card->name;
$delayed = ($card->fromType == 'execution' and !empty($card->delay)) ? "<span class='delayed label label-danger label-badge'>{$lang->execution->delayed}</span>" : '';
$delayed = '';
if($card->fromType == 'execution' or $card->fromType == 'ticket')
{
$delayed = (!empty($card->delay) or (!helper::isZeroDate($card->deadline) and helper::now() > $card->deadline)) ? "<span class='delayed label label-danger label-badge'>{$lang->execution->delayed}</span>" : '';
}
if(common::hasPriv($card->fromType, 'view')) echo "<div class='cardName {$card->fromType}Name'>" . html::a($this->createLink($card->fromType, 'view', "id=$card->fromID"), $name, '', " title='$name'") . "$delayed</div>";
if(!common::hasPriv($card->fromType, 'view')) echo "<div class='cardName {$card->fromType}Name'><div title='$name'>$name</div>$delayed</div>";
if($card->fromType == 'productplan' or $card->fromType == 'build')
@@ -128,6 +134,9 @@ js::set('systemMode', $this->config->systemMode);
<?php if(!helper::isZeroDate($card->begin) and !helper::isZeroDate($card->end) and $card->begin != '2030-01-01' and $card->end != '2030-01-01' and $card->fromType != ''):?>
<span class="time label label-light"><?php echo date("m-d", strtotime($card->begin)) . ' ' . $lang->{$card->fromType}->to . ' ' . date("m-d", strtotime($card->end));?></span>
<?php endif;?>
<?php if($card->fromType == 'ticket' and !helper::isZeroDate($card->deadline) and $card->begin != '2030-01-01' and $card->end != '2030-01-01'):?>
<span class="time label label-light"><?php echo date("m-d", strtotime($card->deadline)) . ' ' . $lang->kanbancard->deadlineAB;?></span>
<?php endif;?>
<?php
if($card->begin == '2030-01-01' or $card->end == '2030-01-01') echo '<span class="date label label-future" title="' . $lang->{$card->fromType}->future . '">' . $lang->{$card->fromType}->future . '</span>';
@@ -135,6 +144,7 @@ js::set('systemMode', $this->config->systemMode);
if($card->fromType == 'execution') $assignedToList = $card->PM;
if($card->fromType == 'build') $assignedToList = $card->builder;
if($card->fromType == 'release' or $card->fromType == 'productplan') $assignedToList = $card->createdBy;
if($card->fromType == 'ticket') $assignedToList = $card->assignedTo;
$count = 0;
$members = '';
?>
@@ -219,6 +229,7 @@ $(function()
if($item.children('.build').length) icon = '<i class="icon icon-ver">';
if($item.children('.productplan').length) icon = '<i class="icon icon-delay">';
if($item.children('.release').length) icon = '<i class="icon icon-publish">';
if($item.children('.ticket').length) icon = '<i class="icon icon-file-text">';
if($item.children('.execution').length && systemMode == 'new') icon = '<i class="icon icon-run">';
if($item.children('.execution').length && systemMode == 'classic') icon = '<i class="icon icon-project">';
+1 -1
View File
@@ -32,7 +32,7 @@
echo html::a(inlink($app->rawMethod, "mode=requirement&type=reviewBy&param=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pagerID=$pageID"), "<span class='text'>{$lang->my->storyMenu->reviewByMe}</span>" . ($type == 'reviewBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'reviewBy' ? ' btn-active-text' : '') . "'");
}
?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php $this->loadModel('search');echo $lang->search->common;?></a>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->search->common;?></a>
</div>
</div>
<div id="mainContent">
+1 -1
View File
@@ -31,7 +31,7 @@
echo html::a(inlink($app->rawMethod, "mode=story&type=reviewBy&param=$param&orderBy=$orderBy&recTotal=$recTotal&recPerPage=$recPerPage&pagerID=$pageID"), "<span class='text'>{$lang->my->storyMenu->reviewByMe}</span>" . ($type == 'reviewBy' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'reviewBy' ? ' btn-active-text' : '') . "'");
}
?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php $this->loadModel('search');echo $lang->search->common;?></a>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->search->common;?></a>
</div>
</div>
<div id="mainContent">
+1 -1
View File
@@ -28,7 +28,7 @@
echo html::a(inlink($app->rawMethod, "mode=$mode&type=assigntome"), "<span class='text'>{$lang->my->assignedToMe}</span>" . ($type == 'assigntome' ? $recTotalLabel : ''), '', "class='btn btn-link" . ($type == 'assigntome' ? ' btn-active-text' : '') . "'");
}
?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php $this->loadModel('search');echo $lang->search->common;?></a>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->search->common;?></a>
</div>
</div>
<div id="mainContent">
+5 -2
View File
@@ -1385,8 +1385,11 @@ class portModel extends model
elseif($control == 'hidden') $html .= html::hidden("$name", $selected);
elseif($control == 'textarea') $html .= '<td>' . html::textarea("$name", $selected, "class='form-control' cols='50' rows='1'") . '</td>';
elseif($control == 'textarea')
{
if($model == 'bug' and $field == 'steps') $selected = str_replace("\n\n\n\n\n\n", '', $selected);
$html .= '<td>' . html::textarea("$name", $selected, "class='form-control' cols='50' rows='1'") . '</td>';
}
elseif($field == 'stepDesc' or $field == 'stepExpect')
{
$stepDesc = $this->process4Testcase($field, $tmpList, $row);
+1 -1
View File
@@ -11,7 +11,7 @@ $(function()
var $title = $('#storyList thead th.c-title');
var headerWidth = $('#storyList thead th.c-title a').innerWidth();
var buttonWidth = $('#storyList thead th.c-title button').innerWidth();
if($title.width() < headerWidth + buttonWidth + 2) $title.width(headerWidth + buttonWidth + 30);
if($title.width() < headerWidth + buttonWidth + 16) $title.width(headerWidth + buttonWidth + 30);
});
$('#storyList td.has-child .story-toggle').each(function()
+2 -1
View File
@@ -14,4 +14,5 @@ th.table-nest-title .check-all {position: absolute; left: 15px; top: 7px;}
.table-statistic {padding-left: 10px;}
td.flex {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center; margin-bottom: 0px;}
td.c-name > .project-type-label {flex: 0 0 36px; padding-right: 2px;}
.c-name > a, .table-children .text-left > a { padding-left: 5px; text-overflow: clip;}
.c-name > a, .table-children .text-left > a, .c-name > span.text-ellipsis { padding-left: 5px; text-overflow: clip;}
span.table-nest-icon.table-nest-toggle {min-width: 22px; max-width: 22px;}
+2 -2
View File
@@ -60,7 +60,7 @@
<th class='c-date'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->testtask->begin);?></th>
<th class='c-date'><?php common::printOrderLink('end', $orderBy, $vars, $lang->testtask->end);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='<?php echo $project->model == 'scrum' ? 'c-actions-5' : 'c-actions-4';?> text-center'><?php echo $lang->actions;?></th>
<th class='c-actions-5 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -102,7 +102,7 @@
{
common::printIcon('testtask', 'cases', "taskID=$task->id", $task, 'list', 'sitemap');
common::printIcon('testtask', 'linkCase', "taskID=$task->id", $task, 'list', 'link');
if(common::hasPriv('execution', 'testreport') and $project->model == 'scrum')
if(common::hasPriv('execution', 'testreport'))
{
echo html::a($this->createLink('execution', 'testreport', "executionID=$task->execution&objectType=execution&extra=$task->id"), '<i class="icon-testreport-browse icon-summary"></i>', '', 'class="btn " title="' . $lang->testreport->browse . '" data-app="project"');
}
+3 -1
View File
@@ -68,11 +68,13 @@ class projectStory extends control
* View a story.
*
* @param int $storyID
* @param int $projectID
* @access public
* @return void
*/
public function view($storyID)
public function view($storyID, $projectID = 0)
{
if($projectID) $this->session->set('project', $projectID, 'project');
$this->session->set('productList', $this->app->getURI(true), 'product');
$story = $this->loadModel('story')->getByID($storyID);
+1
View File
@@ -118,6 +118,7 @@ $lang->story->pri = 'Priorität';
$lang->story->estimate = 'Schätzung(h)';
$lang->story->estimateAB = 'Schätzung(h)';
$lang->story->hour = 'Stunde';
$lang->story->consumed = 'Zeitaufwendig';
$lang->story->status = 'Status';
$lang->story->statusAB = 'Status';
$lang->story->subStatus = 'Sub Status';
+1
View File
@@ -118,6 +118,7 @@ $lang->story->pri = 'Priority';
$lang->story->estimate = "Estimates";
$lang->story->estimateAB = 'Est.';
$lang->story->hour = $lang->hourCommon;
$lang->story->consumed = 'Consumed';
$lang->story->status = 'Status';
$lang->story->statusAB = 'Status';
$lang->story->subStatus = 'Sub Status';
+1
View File
@@ -118,6 +118,7 @@ $lang->story->pri = 'Priorité';
$lang->story->estimate = 'Estimation';
$lang->story->estimateAB = 'Esti.(h)';
$lang->story->hour = 'Heures';
$lang->story->consumed = 'Long';
$lang->story->status = 'Statut';
$lang->story->statusAB = 'Statut';
$lang->story->subStatus = 'Sous-statut';
+1
View File
@@ -116,6 +116,7 @@ $lang->story->pri = 'Ưu tiên';
$lang->story->estimate = "{$lang->hourCommon} dự tính";
$lang->story->estimateAB = 'DT.' . $lang->hourCommon == 'giờ' ? '(giờ)' : '(SP)';
$lang->story->hour = $lang->hourCommon;
$lang->story->consumed = 'Mất thời gian';
$lang->story->status = 'Tình trạng';
$lang->story->subStatus = 'Tình trạng con';
$lang->story->stage = 'Giai đoạn';
+1
View File
@@ -118,6 +118,7 @@ $lang->story->pri = '优先级';
$lang->story->estimate = "预计{$lang->hourCommon}";
$lang->story->estimateAB = '预计';
$lang->story->hour = $lang->hourCommon;
$lang->story->consumed = '耗时';
$lang->story->status = '当前状态';
$lang->story->statusAB = '状态';
$lang->story->subStatus = '子状态';
+1
View File
@@ -107,6 +107,7 @@ $lang->story->pri = '優先順序';
$lang->story->estimate = "預計{$lang->hourCommon}";
$lang->story->estimateAB = '預計';
$lang->story->hour = $lang->hourCommon;
$lang->story->consumed = '耗時';
$lang->story->status = '當前狀態';
$lang->story->subStatus = '子狀態';
$lang->story->stage = '所處階段';
+1 -1
View File
@@ -4641,7 +4641,7 @@ class storyModel extends model
if($tab == 'project')
{
$storyLink = helper::createLink('projectstory', 'view', "storyID=$story->id");
$storyLink = helper::createLink('projectstory', 'view', "storyID=$story->id&project={$this->session->project}");
$canView = common::hasPriv('projectstory', 'view');
}
elseif($tab == 'execution')
+3 -3
View File
@@ -105,17 +105,17 @@ $config->task->datatable->fieldList['deadline']['control'] = 'date';
$config->task->datatable->fieldList['estimate']['title'] = 'estimateAB';
$config->task->datatable->fieldList['estimate']['fixed'] = 'no';
$config->task->datatable->fieldList['estimate']['width'] = '55';
$config->task->datatable->fieldList['estimate']['width'] = '65';
$config->task->datatable->fieldList['estimate']['required'] = 'no';
$config->task->datatable->fieldList['consumed']['title'] = 'consumedAB';
$config->task->datatable->fieldList['consumed']['fixed'] = 'no';
$config->task->datatable->fieldList['consumed']['width'] = '55';
$config->task->datatable->fieldList['consumed']['width'] = '65';
$config->task->datatable->fieldList['consumed']['required'] = 'no';
$config->task->datatable->fieldList['left']['title'] = 'leftAB';
$config->task->datatable->fieldList['left']['fixed'] = 'no';
$config->task->datatable->fieldList['left']['width'] = '55';
$config->task->datatable->fieldList['left']['width'] = '65';
$config->task->datatable->fieldList['left']['required'] = 'no';
$config->task->datatable->fieldList['progress']['title'] = 'progressAB';
+39 -8
View File
@@ -1219,7 +1219,7 @@ class task extends control
{
if(empty($orderBy))
{
$orderBy = 'order_asc,id';
$orderBy = 'id_desc';
}
else
{
@@ -1227,14 +1227,35 @@ class task extends control
$orderBy .= preg_replace('/(order_|date_)/', ',id_', $orderBy);
}
}
if(!$orderBy) $orderBy = 'date_asc';
$this->view->title = $this->lang->task->record;
$this->view->task = $task;
$this->view->from = $from;
$this->view->orderBy = $orderBy;
$this->view->efforts = $this->task->getTaskEstimate($taskID, '', '', $orderBy);
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
if(!$orderBy) $orderBy = 'id_desc';
/* Set the fold state of the current task. */
$referer = strtolower($_SERVER['HTTP_REFERER']);
if(strpos($referer, 'recordestimate') and $this->cookie->taskEffortFold !== false)
{
$taskEffortFold = $this->cookie->taskEffortFold;
}
else
{
$taskEffortFold = 0;
$currentAccount = $this->app->user->account;
if($task->assignedTo == $currentAccount) $taskEffortFold = 1;
if(!empty($task->team))
{
$teamMember = array_column($task->team, 'account');
if(in_array($currentAccount, $teamMember)) $taskEffortFold = 1;
}
}
$this->view->title = $this->lang->task->record;
$this->view->task = $task;
$this->view->from = $from;
$this->view->orderBy = $orderBy;
$this->view->efforts = $this->task->getTaskEstimate($taskID, '', '', $orderBy);
$this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter');
$this->view->taskEffortFold = $taskEffortFold;
$this->display();
}
@@ -1859,6 +1880,16 @@ class task extends control
if(!isset($this->view->members[$this->view->task->finishedBy])) $this->view->members[$this->view->task->finishedBy] = $this->view->task->finishedBy;
if(!empty($this->view->task->team))
{
$teamAccounts = array_column($this->view->task->team, 'account');
$teamMembers = array();
foreach($this->view->members as $account => $name)
{
if(!$account or in_array($account, $teamAccounts)) $teamMembers[$account] = $name;
}
$this->view->teamMembers = $teamMembers;
}
$this->view->title = $this->view->execution->name . $this->lang->colon . $this->lang->task->activate;
$this->view->position[] = $this->lang->task->activate;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
+6 -5
View File
@@ -7,7 +7,6 @@
#modalTeam .modal-header .modal-title {font-size: 13px; line-height: 24px;}
#taskTeamEditor tr {padding: 8px 7px 8px 7px;}
#taskTeamEditor td .chosen-single .chosen-search input,
#taskTeamEditor tr td .chosen-single {height: 35px; line-height: 24px;}
#taskTeamEditor td .chosen-single .chosen-search::before {top: 10px;}
#taskTeamEditor tr td:first-child {width: 40px; position: relative;}
.team-number {display: inline-block; width: 20px; height: 20px; line-height: 20px; border-radius: 10px; text-align: center; background: #f4f5f7;}
@@ -19,8 +18,10 @@
#modalTeam .modal-content input[type="text"]::-webkit-input-placeholder{color: #c4c4c4;text-align: left;}
#modalTeam .modal-content input[type="text"]::-moz-placeholder{color: #c4c4c4;text-align: left;}
#modalTeam .modal-content input[type="text"]::-ms-input-placeholder{color: #c4c4c4;text-align: left;}
#modalTeam #team_chosen span {line-height: 24px;}
#modalTeam #team_chosen a.chosen-default > span {color: #c4c4c4;}
#modalTeam .input-control input[type="text"]::input-placeholder{text-align: right;}
#modalTeam .input-control input[type="text"]::-webkit-input-placeholder{text-align: right;}
#modalTeam .input-control input[type="text"]::-moz-placeholder{text-align: right;}
#modalTeam .input-control input[type="text"]::-ms-input-placeholder{text-align: right;}
#modalTeam .input-control input[type="text"]::input-placeholder{text-align: center;}
#modalTeam .input-control input[type="text"]::-webkit-input-placeholder{text-align: center;}
#modalTeam .input-control input[type="text"]::-moz-placeholder{text-align: center;}
#modalTeam .input-control input[type="text"]::-ms-input-placeholder{text-align: center;}
+2 -1
View File
@@ -29,5 +29,6 @@
.keep-row-height {height: 32px;}
#modalTeam .modal-dialog {min-height: 120px; width: 520px; color: #3c4353;}
#taskTeamEditor .chosen-single {width: 200px;}
#taskTeamEditor .hourBox {padding-bottom: 7px; width: 135px;}
#taskTeamEditor .estimateBox {width: 120px;}
#modalTeam .modal-content {padding: 0;}
+1
View File
@@ -0,0 +1 @@
#mainContent {padding-left: 0;}
+5
View File
@@ -21,3 +21,8 @@
.table.has-sort-head thead>tr>th>a:after, .table.has-sort-head thead>tr>th>a:before {top: -7px;}
.table.has-sort-head thead>tr>th>a:hover, .table.has-sort-head thead>tr>th>a:hover:after, .table.has-sort-head thead>tr>th>a:hover:before {color: #000;}
#toggleFoldIcon:hover {cursor: pointer;}
#toggleFoldIcon .icon-border {width: 20px; height: 20px; border-radius: 8px; border: 1px solid #D5E5FF;}
#toggleFoldIcon .icon-border > .icon {color: #3785FF;}
#toggleFoldIcon .text {color: #3785FF;}
+144 -50
View File
@@ -1,56 +1,158 @@
$('#confirmButton').click(function()
$(function()
{
var memberCount = '';
var totalEstimate = 0;
var totalConsumed = oldConsumed;
var totalLeft = 0;
var error = false;
$('select[name^=team]').each(function()
$('#confirmButton').click(function()
{
if($(this).val() == '') return;
memberCount++;
var $tr = $(this).closest('tr');
var account = $(this).find('option:selected').text();
var estimate = parseFloat($tr.find('[name^=teamEstimate]').val());
if(!isNaN(estimate)) totalEstimate += estimate;
if($tr.hasClass('member-wait') && (isNaN(estimate) || estimate == 0))
var memberCount = '';
var totalEstimate = 0;
var totalConsumed = oldConsumed;
var totalLeft = 0;
var error = false;
$('select[name^=team]').each(function()
{
bootbox.alert(account + ' ' + estimateNotEmpty);
error = true;
return false;
if($(this).val() == '') return;
memberCount++;
var $tr = $(this).closest('tr');
var account = $(this).find('option:selected').text();
var estimate = parseFloat($tr.find('[name^=teamEstimate]').val());
if(!isNaN(estimate)) totalEstimate += estimate;
if($tr.hasClass('member-wait') && (isNaN(estimate) || estimate <= 0))
{
bootbox.alert(account + ' ' + estimateNotEmpty);
error = true;
return false;
}
var consumed = parseFloat($tr.find('[name^=teamConsumed]').val());
if(!isNaN(consumed)) totalConsumed += consumed;
var $left = $tr.find('[name^=teamLeft]');
var left = parseFloat($left.val());
if(!isNaN(left)) totalLeft += left;
if(!$left.prop('readonly') && $tr.hasClass('member-wait') && (isNaN(left) || left <= 0))
{
bootbox.alert(account + ' ' + leftNotEmpty);
error = true;
return false;
}
})
if(error) return false;
if(memberCount < 2)
{
bootbox.alert(teamMemberError);
return false;
}
var consumed = parseFloat($tr.find('[name^=teamConsumed]').val());
if(!isNaN(consumed)) totalConsumed += consumed;
$('#left').val(totalLeft);
updateAssignedTo();
var $left = $tr.find('[name^=teamLeft]');
var left = parseFloat($left.val());
if(!isNaN(left)) totalLeft += left;
if(!$left.prop('readonly') && $tr.hasClass('member-wait') && (isNaN(left) || left == 0))
{
bootbox.alert(account + ' ' + leftNotEmpty);
error = true;
return false;
}
})
$('.close').click();
});
if(error) return false;
if(memberCount < 2)
$('#multiple').on('click', function()
{
bootbox.alert(teamMemberError);
return false;
}
var showTeam = $(this).is(":checked");
$('#assignedTo').val('');
$('#left').val('');
$('#dataPlanGroup').removeClass('required');
$('.multi-append').empty();
$('.teamTemplate select, .teamTemplate input').val('');
$('.teamTemplate input[name^=teamConsumed]').val('0');
$('.teamTemplate select').trigger('chosen:updated');
$('#left').val(totalLeft);
updateAssignedTo();
/* Reset team modal. */
var oldTeamCount = $('#taskTeamEditor select:disabled').length;
var removeCount = oldTeamCount > 6 ? 1 : (5 - oldTeamCount);
$('#taskTeamEditor tr.teamTemplate').filter(':gt(' + removeCount + ')').remove();
$('.member-done').find('input[name^=teamLeft]').val(0);
$('.close').click();
/* Reset assignedTo select.*/
$('#assignedTo_chosen').remove();
$('#assignedTo').replaceWith(assignedToHtml);
if(showTeam)
{
$('#assignedTo').attr('disabled', true);
$('#left').attr('readonly', true);
$('.team-group').removeClass('hidden');
}
else
{
$('.team-group').addClass('hidden');
$('#assignedTo').removeAttr('disabled');
$('#left').removeAttr('readonly');
$('#dataPlanGroup').addClass('required');
}
$('#assignedTo').chosen();
$('#assignedTo').trigger('chosen:updated');
});
$('#assignedTo').on('change', setTeamUser);
$('#left').on('input', setTeamUser);
$('#submit').on('click', function()
{
if(isMultiple)
{
var multiple = $('#multiple').is(":checked");
if(!multiple)
{
var assignedTo = $('#assignedTo').val();
if(!assignedTo)
{
bootbox.alert(teamNotEmpty);
return false;
}
}
var estimate = parseInt($('#left').val());
if(isNaN(estimate) || estimate <= 0)
{
bootbox.alert(multiple ? teamLeftEmpty : leftNotEmpty);
return false;
}
$('#assignedTo').val('');
}
});
});
/**
* Set team user form.
*
* @access public
* @return void
*/
function setTeamUser()
{
$('.multi-append').empty();
var assignedTo = $('#assignedTo').val();
var estimate = parseInt($('#left').val());
if(!assignedTo || !estimate) return;
if(taskMode == 'multi')
{
$('.member-done').each(function()
{
if($(this).find('select').val() == assignedTo) $(this).find('input[name^=teamLeft]').val(estimate);
});
}
else
{
var teamLine = '<input type="hidden" name="team[]" value="' + assignedTo + '">';
teamLine += '<input type="hidden" name="teamSource[]" value="' + assignedTo + '">';
teamLine += '<input type="hidden" name="teamEstimate[]" value="' + estimate + '">';
teamLine += '<input type="hidden" name="teamConsumed[]" value="0">';
teamLine += '<input type="hidden" name="teamLeft[]" value="' + estimate + '">';
$('.multi-append').html(teamLine);
}
}
/**
* Update assignedTo.
*
@@ -77,15 +179,7 @@ function updateAssignedTo()
html += "<option value='" + account + "' title='" + realName + "'" + selected + ">" + realName + "</option>";
});
if(mode == 'multi' && isTeamMember && mode != 'linear')
{
$('[name=assignedTo]').removeAttr('disabled').trigger('chosen:updated');
}
else
{
$('[name=assignedTo]').attr('disabled', 'disabled').trigger('chosen:updated');
}
$('[name=assignedTo]').attr('disabled', 'disabled').trigger('chosen:updated');
}
else
{
+5
View File
@@ -16,3 +16,8 @@ $(document).ready(function()
}
});
});
$(function()
{
parent.$(' #triggerModal .modal-dialog').css('width', '800px');
});
+29
View File
@@ -74,4 +74,33 @@ $(function()
{
$(this).prev().datetimepicker('show');
});
$('#toggleFoldIcon').click(function()
{
var fold = $(this).find('.icon-angle-down').length > 0;
var $icon = $(this).find('.icon-border > i');
var $text = $(this).find('.text');
$.cookie('taskEffortFold', fold ? 0 : 1);
if(fold)
{
/* Update icon and text. */
$icon.removeClass('icon-angle-down')
.addClass('icon-angle-top');
$text.text(foldEffort);
/* Show all efforts. */
$('.taskEffort > tbody > tr').removeClass('hidden');
}
else
{
$icon.removeClass('icon-angle-top')
.addClass('icon-angle-down');
$text.text(unfoldEffort);
/* Efforts whose number is greater than 3 are hidden. */
$('.taskEffort > tbody > tr').filter(':gt(2)').addClass('hidden');
}
});
})
+5
View File
@@ -60,6 +60,9 @@ $lang->task->replace = 'Replace';
$lang->task->myEffort = 'My Effort';
$lang->task->allEffort = 'Team Effort';
$lang->task->teamOrder = 'Order';
$lang->task->manageTeam = 'Manage Team';
$lang->task->unfoldEffort = 'Unfold Effort';
$lang->task->foldEffort = 'Fold Effort';
$lang->task->common = 'Aufgabe';
$lang->task->id = 'ID';
@@ -277,6 +280,8 @@ $lang->task->error->alreadyConsumed = 'The currently selected parent task has
$lang->task->error->date = 'The date should be <= today.';
$lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left" cannot be 0';
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -60,6 +60,9 @@ $lang->task->replace = 'Replace';
$lang->task->myEffort = 'My Effort';
$lang->task->allEffort = 'Team Effort';
$lang->task->teamOrder = 'Order';
$lang->task->manageTeam = 'Manage Team';
$lang->task->unfoldEffort = 'Unfold Effort';
$lang->task->foldEffort = 'Fold Effort';
$lang->task->common = 'Task';
$lang->task->id = 'ID';
@@ -277,6 +280,8 @@ $lang->task->error->alreadyConsumed = 'The currently selected parent task has
$lang->task->error->date = 'The date should be <= today.';
$lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left" cannot be 0';
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -60,6 +60,9 @@ $lang->task->replace = 'Replace';
$lang->task->myEffort = 'My Effort';
$lang->task->allEffort = 'Team Effort';
$lang->task->teamOrder = 'Order';
$lang->task->manageTeam = 'Manage Team';
$lang->task->unfoldEffort = 'Unfold Effort';
$lang->task->foldEffort = 'Fold Effort';
$lang->task->common = 'Tâche';
$lang->task->id = 'ID';
@@ -277,6 +280,8 @@ $lang->task->error->alreadyConsumed = 'The currently selected parent task has
$lang->task->error->date = 'The date should be <= today.';
$lang->task->error->leftEmptyAB = 'When the task status is %s, "Hours Left" cannot be 0';
$lang->task->error->leftEmpty = 'Task#%sWhen the task status is %s, "Left" cannot be 0';
$lang->task->error->notempty = '%s must be > 0.';
$lang->task->error->teamLeftEmpty = 'Please maintain team hours.';
/* Report. */
$lang->task->report = new stdclass();
+5
View File
@@ -60,6 +60,9 @@ $lang->task->replace = '替换';
$lang->task->myEffort = '我的日志';
$lang->task->allEffort = '团队日志';
$lang->task->teamOrder = '工序';
$lang->task->manageTeam = '维护团队';
$lang->task->unfoldEffort = '展开日志';
$lang->task->foldEffort = '收起日志';
$lang->task->common = '任务';
$lang->task->id = '编号';
@@ -277,6 +280,8 @@ $lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。
$lang->task->error->date = '日期不能大于今天';
$lang->task->error->leftEmptyAB = '任务状态为%s时,预计剩余不能为0';
$lang->task->error->leftEmpty = 'Task#%s任务状态为%s时,剩余不能为0';
$lang->task->error->notempty = '%s必须大于0。';
$lang->task->error->teamLeftEmpty = '请维护团队工时。';
/* Report. */
$lang->task->report = new stdclass();
+6
View File
@@ -2282,6 +2282,12 @@ class taskModel extends model
return false;
}
if(empty($task->left))
{
dao::$errors[] = sprintf($this->lang->task->error->notempty, $this->lang->task->left);
return false;
}
if(!empty($oldTask->team))
{
$this->manageTaskTeam($oldTask->mode, $oldTask->id, $task->status);
+19 -9
View File
@@ -17,9 +17,15 @@
<?php js::set('currentUser', $app->user->account);?>
<?php js::set('members', $members);?>
<?php js::set('teamMemberError', $lang->task->error->teamMember);?>
<?php js::set('teamLeftEmpty', $lang->task->error->teamLeftEmpty);?>
<?php js::set('totalLeftError', sprintf($this->lang->task->error->leftEmptyAB, $this->lang->task->statusList[$task->status]));?>
<?php js::set('estimateNotEmpty', sprintf($lang->error->notempty, $lang->task->estimate))?>
<?php js::set('leftNotEmpty', sprintf($lang->error->notempty, $lang->task->left))?>
<?php js::set('estimateNotEmpty', sprintf($lang->task->error->notempty, $lang->task->estimate))?>
<?php js::set('leftNotEmpty', sprintf($lang->task->error->notempty, $lang->task->left))?>
<?php js::set('teamNotEmpty', sprintf($lang->error->notempty, $lang->task->assignedTo))?>
<?php $isMultiple = !empty($task->team);?>
<?php js::set('isMultiple', $isMultiple);?>
<?php js::set('taskMode', $task->mode);?>
<?php js::set('assignedToHtml', html::select('assignedTo', $teamMembers, '', "class='form-control' disabled"));?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
@@ -34,7 +40,6 @@
<form method='post' target='hiddenwin'>
<table class='table table-form'>
<?php $isMultiple = !empty($task->team);?>
<?php if($isMultiple):?>
<tr>
<th class='thWidth'><?php echo $lang->task->mode;?></th>
@@ -45,17 +50,17 @@
<tr>
<th class='thWidth'><?php echo $lang->task->assignedTo;?></th>
<td class='w-p35-f'>
<div class="input-group" id="dataPlanGroup">
<?php echo html::select('assignedTo', $members, $task->finishedBy, "class='form-control chosen'" . ($isMultiple ? ' disabled' : ''));?>
<div class="input-group<?php if($isMultiple) echo ' required';?>" id="dataPlanGroup">
<?php echo html::select('assignedTo', $isMultiple ? $teamMembers : $members, $isMultiple ? '' : $task->finishedBy, "class='form-control chosen'");?>
<?php if($isMultiple):?>
<span class="input-group-btn team-group"><a class="btn br-0" href="#modalTeam" data-toggle="modal"><?php echo $lang->task->team;?></a></span>
<span class="input-group-btn team-group hidden"><a class="btn br-0" href="#modalTeam" data-toggle="modal"><?php echo $lang->task->team;?></a></span>
<?php endif;?>
</div>
</td>
<td>
<?php if($isMultiple):?>
<div class="checkbox-primary c-multipleTask affair">
<input type="checkbox" name="multiple" value="1" id="multiple" checked disabled /><label for="multiple" class="no-margin"><?php echo $lang->task->multiple;?></label>
<input type="checkbox" name="multiple" value="1" id="multiple" /><label for="multiple" class="no-margin"><?php echo $lang->task->manageTeam;?></label>
</div>
<?php endif;?>
</td>
@@ -65,7 +70,7 @@
<th><?php echo $lang->task->left;?></th>
<td>
<div class='input-group'>
<?php echo html::input('left', '', "class='form-control'" . ($isMultiple ? ' readonly' : ''));?>
<?php echo html::input('left', '', "class='form-control'");?>
<span class='input-group-addon'><?php echo $lang->task->hour;?></span>
</div>
</td>
@@ -105,7 +110,12 @@
<?php include __DIR__ . DS . 'taskteam.html.php';?>
</tbody>
<tfoot>
<tr><td colspan='3' class='text-center form-actions'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "id='confirmButton' class='btn btn-primary btn-wide'");?></td></tr>
<tr>
<td colspan='4' class='text-center form-actions'>
<div class='multi-append'></div>
<?php echo html::a('javascript:void(0)', $lang->confirm, '', "id='confirmButton' class='btn btn-primary btn-wide'");?>
</td>
</tr>
</tfoot>
</table>
</div>
-1
View File
@@ -64,7 +64,6 @@
</tfoot>
</table>
</form>
<hr class='small' />
<?php endif;?>
</div>
</div>
+13 -2
View File
@@ -50,7 +50,7 @@ foreach($efforts as $key => $effort)
<div class='tab-content'>
<div class='tab-pane' id='legendMyEffort'>
<?php if(!empty($myOrders)):?>
<table class='table table-bordered table-fixed table-recorded has-sort-head'>
<table class='table table-bordered table-fixed table-recorded has-sort-head taskEffort'>
<thead>
<tr class='text-center'>
<?php
@@ -69,11 +69,13 @@ foreach($efforts as $key => $effort)
</tr>
</thead>
<tbody>
<?php $i = 1;?>
<?php foreach($myOrders as $order => $count):?>
<?php $showOrder = false;?>
<?php foreach($myEfforts[$order] as $effort):?>
<?php if($effort->account != $this->app->user->account) continue;?>
<tr class="text-center">
<?php $hidden = ($taskEffortFold and $i > 3) ? 'hidden' : ''?>
<tr class="text-center <?php echo $hidden;?>">
<?php if(!$showOrder):?>
<td rowspan='<?php echo $count;?>'><?php echo $allOrders[$order];?></td>
<?php $showOrder = true;?>
@@ -93,10 +95,19 @@ foreach($efforts as $key => $effort)
?>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
<?php endforeach;?>
</tbody>
</table>
<?php if($i > 4):?>
<div id='toggleFoldIcon'>
<?php $icon = $taskEffortFold ? 'icon-angle-down' : 'icon-angle-top'?>
<?php $iconText = $taskEffortFold ? $lang->task->unfoldEffort : $lang->task->foldEffort;?>
<span class='icon-border'><i class="icon <?php echo $icon;?>"></i></span>
<span class='text'><?php echo $iconText;?></span>
</div>
<?php endif;?>
<?php endif;?>
</div>
<div class='tab-pane' id='legendAllEffort'>
+16 -2
View File
@@ -12,6 +12,9 @@
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php include '../../common/view/datepicker.html.php';?>
<?php js::set('foldEffort', $lang->task->foldEffort);?>
<?php js::set('unfoldEffort', $lang->task->unfoldEffort);?>
<?php js::set('taskID', $task->id);?>
<?php if(!$this->task->canOperateEffort($task) and empty($myOrders)):?>
<style>#mainContent {min-height: unset;}</style>
<?php endif;?>
@@ -59,7 +62,7 @@ if(!empty($members) && $task->mode == 'linear')
<?php if(!empty($task->team) and $task->mode == 'linear'):?>
<?php include __DIR__ . '/lineareffort.html.php';?>
<?php else:?>
<table class='table table-bordered table-fixed table-recorded has-sort-head'>
<table class='table table-bordered table-fixed table-recorded has-sort-head taskEffort'>
<thead>
<tr class='text-center'>
<?php $vars = "taskID=$task->id&from=$from&orderBy=%s";?>
@@ -72,8 +75,10 @@ if(!empty($members) && $task->mode == 'linear')
</tr>
</thead>
<tbody>
<?php $i = 1;?>
<?php foreach($efforts as $effort):?>
<tr class="text-center">
<?php $hidden = ($taskEffortFold and $i > 3) ? 'hidden' : ''?>
<tr class="text-center <?php echo $hidden;?>">
<td><?php echo $effort->date;?></td>
<td><?php echo zget($users, $effort->account);?></td>
<td class="text-left" title="<?php echo $effort->work;?>"><?php echo $effort->work;?></td>
@@ -87,9 +92,18 @@ if(!empty($members) && $task->mode == 'linear')
?>
</td>
</tr>
<?php $i ++;?>
<?php endforeach;?>
</tbody>
</table>
<?php if(count($efforts) > 3):?>
<div id='toggleFoldIcon'>
<?php $icon = $taskEffortFold ? 'icon-angle-down' : 'icon-angle-top'?>
<?php $iconText = $taskEffortFold ? $lang->task->unfoldEffort : $lang->task->foldEffort;?>
<span class='icon-border'><i class="icon <?php echo $icon;?>"></i></span>
<span class='text'><?php echo $iconText;?></span>
</div>
<?php endif;?>
<?php endif;?>
<?php endif;?>
<?php if(!$this->task->canOperateEffort($task) and empty($myOrders)):?>
+17 -5
View File
@@ -3,7 +3,19 @@
#taskTeamEditor .estimateBox span {background-color: #fff;}
#taskTeamEditor .estimateBox input {background-color: #fff; border-right-width: 0px;}
#taskTeamEditor input, #taskTeamEditor span, #taskTeamEditor .chosen-container > a {border-color: #eee;}
#taskTeamEditor td.sort-handler {padding-bottom: 12px;}
</style>
<?php if($app->rawMethod != 'create'):?>
<style>
#modalTeam .modal-dialog {width: 855px;}
#taskTeamEditor .hourBox {padding-bottom: 1px;}
</style>
<?php endif;?>
<?php if($app->rawMethod == 'assignto'):?>
<style>
#taskTeamEditor td.sort-handler {width: 70px !important;}
</style>
<?php endif;?>
<?php $hiddenArrow = (empty($task->mode) or $task->mode == 'linear') ? '' : 'hidden';?>
<?php $i = 1;?>
<?php if(!empty($task->team)):?>
@@ -31,11 +43,11 @@ if($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = fal
<i class="icon icon-angle-down <?php echo $hiddenArrow;?>"></i>
</td>
<td class='w-250px'>
<?php echo html::select("team[]", $members, $member->account, "class='form-control chosen'" . ($memberDisabled ? ' disabled' : ''))?>
<?php echo html::select("team[]", $members, $member->account, "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'" . ($memberDisabled ? ' disabled' : ''))?>
<?php echo html::hidden("teamSource[]", $member->account);?>
<?php if($memberDisabled) echo html::hidden("team[]", $member->account);?>
</td>
<td>
<td class='hourBox'>
<div class='input-group'>
<div class="input-control has-icon-right">
<?php echo html::input("teamEstimate[]", (float)$member->estimate, "class='form-control text-center' placeholder='{$lang->task->estimate}'" . ($hourDisabled ? ' readonly' : ''))?>
@@ -51,7 +63,7 @@ if($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = fal
</div>
</div>
</td>
<td class='w-130px sort-handler'>
<td class='w-100px sort-handler'>
<button type="button" <?php echo $memberDisabled ? 'disabled' : '';?> class="btn btn-link btn-sm btn-icon btn-add"><i class="icon icon-plus"></i></button>
<button type="button" <?php echo $memberDisabled ? 'disabled' : '';?> class="btn btn-link btn-sm btn-icon btn-delete"><i class="icon icon-trash"></i></button>
<?php if(isset($task->mode) and $task->mode == 'linear'):?>
@@ -68,10 +80,10 @@ if($task->mode == 'multi' and $app->rawMethod == 'activate') $hourDisabled = fal
<i class="icon icon-angle-down <?php echo $hiddenArrow;?>"></i>
</td>
<td class='w-240px'>
<?php echo html::select("team[]", $members, '', "class='form-control chosen'")?>
<?php echo html::select("team[]", $members, '', "class='form-control chosen' data-placeholder='{$lang->task->assignedTo}'")?>
<?php echo html::hidden("teamSource[]", '');?>
</td>
<td class='w-130px'>
<td class='hourBox'>
<?php if(empty($task->team)):?>
<div class='input-group estimateBox'>
<?php echo html::input("teamEstimate[]", '', "class='form-control text-center' placeholder='{$lang->task->estimateAB}'") ?>
+3 -1
View File
@@ -122,8 +122,10 @@ body.xxc-embed.m-productplan-view,body.xxc-embed.m-bug-browse,body.xxc-embed.m-p
.setting-input {width: 64px; height: 20px; margin: 0 4px; text-align: center;}
.setting-input.disabled,.setting-input[disabled="disabled"] {color: #C4C4C4;}
.width-radio-row {display: flex;}
#dataform .width-radio-row.required:after {top: 1px; left: 360px;}
#dataform .width-radio-row.required:after {top: 1px; left: 215px;}
#dataform .width-radio-row.mt10.required:after {top: 1px; left: 355px;}
.mt10 {margin-top: 10px;}
#dataform tr > th {vertical-align: middle;}
#programTableList > tr:hover {background: #E6F0FFCC;}