diff --git a/lib/zin/wg/formbatchitem/v1.php b/lib/zin/wg/formbatchitem/v1.php index 56c6332e09..09c151cded 100644 --- a/lib/zin/wg/formbatchitem/v1.php +++ b/lib/zin/wg/formbatchitem/v1.php @@ -94,7 +94,7 @@ class formBatchItem extends wg ( set::class('form-label form-batch-label', $labelClass, $strong ? 'font-bold' : null, $required ? 'required' : null), set($labelProps), - empty($label) ? $name : $label + $label ), empty($tip) ? null : new btn ( diff --git a/module/task/control.php b/module/task/control.php index 812f306055..5952e4f8fc 100755 --- a/module/task/control.php +++ b/module/task/control.php @@ -59,6 +59,7 @@ class task extends control /* Submit the data process after create the task form. */ if(!empty($_POST)) { + a($_POST);die; $taskData = $this->taskZen->buildTaskForCreate($this->post->execution); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); diff --git a/module/task/css/create.ui.css b/module/task/css/create.ui.css index 4ccc595031..3a47d2c2a7 100644 --- a/module/task/css/create.ui.css +++ b/module/task/css/create.ui.css @@ -5,3 +5,13 @@ #taskCreateForm .empty-story-tip .input-control-suffix .btn:hover:before {background: none;} #taskCreateForm .selectStoryLabel {top: 50%;} #testStoryBox th.required:before {content: '*'; color: rgba(var(--color-danger-500-rgb),var(--tw-text-opacity)); margin-right: 0.25rem; position: relative; top: 0.125rem;} + +#modalTeam .table tr {border:none} +.team-number {display: inline-block; width: 20px; height: 20px; line-height: 20px; border-radius: 10px; text-align: center; background: #f4f5f7;} + +.assignedToBox {align-items: center !important} +.assignedToBox .add-team {margin-bottom: 5px} +.assignedToList {display: flex; align-items: center; flex-wrap: wrap} +.assignedToList .label, .assignedToList .icon{margin-right: 5px; margin-bottom: 5px} + +:root {--modal-base: 45rem;} diff --git a/module/task/js/create.ui.js b/module/task/js/create.ui.js index 6185fdf408..ac8391c776 100644 --- a/module/task/js/create.ui.js +++ b/module/task/js/create.ui.js @@ -20,19 +20,17 @@ $(function() * @access public * @return void */ -function showTeamBox() +function toggleTeam() { if($('[name^=multiple]').prop('checked')) { - $('.team-group').removeClass('hidden'); - $('.modeBox').removeClass('hidden'); - $('#estimate').attr('readonly', true); + $('.add-team').removeClass('hidden'); + $('#assignedTo').addClass('hidden'); } else { - $('.team-group').addClass('hidden'); - $('.modeBox').addClass('hidden'); - $('#estimate').removeAttr('readonly'); + $('.add-team').addClass('hidden'); + $('#assignedTo').removeClass('hidden'); } } @@ -380,3 +378,62 @@ window.removeItem = function(obj) if($('#testStoryBox').find('tbody tr').length == 1) return false; $(obj).closest('tr').remove(); } + +$('#modalTeam').on('click.saveTeam', '.toolbar-item', function() +{ + $('div.assignedToList').html(''); + + let team = []; + let totalEstimate = 0; + let error = false; + let mode = $('[name="mode"]').val(); + let assignedToList = ''; + + $(this).closest('form').find('select[name^="team"]').each(function(index) + { + if($(this).val() == '') return; + + const selectObj = $(this)[0]; + + let realname = selectObj.options[selectObj.selectedIndex].text; + if(!team.includes(realname)) team.push(realname); + + let estimate = parseFloat($(this).closest('tr').find('[name^=teamEstimate]').val()); + if(!isNaN(estimate) && estimate > 0) totalEstimate += estimate; + + if(realname != '' && (isNaN(estimate) || estimate <= 0)) + { + zui.Modal.alert(realname + ' ' + estimateNotEmpty); + error = true; + return false; + } + + assignedToList += "" + realname + ''; + assignedToList += ''; + }) + + if(error) return false; + + if(team.length < 2) + { + bootbox.alert(teamMemberError); + return false; + } + else + { + $('#estimate').val(totalEstimate); + } + + /* 将选中的团队成员展示在指派给后面. */ + const regex = /<\/i>(?!.*<\/i>)/; + assignedToList = assignedToList.replace(regex, ''); + $('div.assignedToList').prepend(assignedToList); + + zui.Modal.hide(); + return false; +}) + +function onPageUnmount() +{ + $('#modalTeam').off('.saveTeam'); +} diff --git a/module/task/lang/de.php b/module/task/lang/de.php index 25450b53b1..a8616d3dd8 100644 --- a/module/task/lang/de.php +++ b/module/task/lang/de.php @@ -168,6 +168,7 @@ $lang->task->lblPri = 'P'; $lang->task->lblHour = '(h)'; $lang->task->lblTestStory = 'Story Tested'; $lang->task->teamMember = 'Team Member'; +$lang->task->addMember = 'Add Member'; $lang->task->to = 'To'; $lang->task->suffixHour = 'H'; diff --git a/module/task/lang/en.php b/module/task/lang/en.php index 3dd296c5ca..68fc0d1ccb 100755 --- a/module/task/lang/en.php +++ b/module/task/lang/en.php @@ -168,6 +168,7 @@ $lang->task->lblPri = 'P'; $lang->task->lblHour = '(h)'; $lang->task->lblTestStory = 'Story Tested'; $lang->task->teamMember = 'Team Member'; +$lang->task->addMember = 'Add Member'; $lang->task->to = 'To'; $lang->task->suffixHour = 'H'; diff --git a/module/task/lang/fr.php b/module/task/lang/fr.php index f1c5b6c178..1d9959f3bf 100644 --- a/module/task/lang/fr.php +++ b/module/task/lang/fr.php @@ -168,6 +168,7 @@ $lang->task->lblPri = 'P'; $lang->task->lblHour = '(h)'; $lang->task->lblTestStory = 'Story Testée'; $lang->task->teamMember = 'Team Member'; +$lang->task->addMember = 'Add Member'; $lang->task->to = 'To'; $lang->task->suffixHour = 'H'; diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index 31b9430c21..515e3ddaec 100755 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -168,6 +168,7 @@ $lang->task->lblPri = 'P'; $lang->task->lblHour = '(h)'; $lang->task->lblTestStory = "测试{$lang->SRCommon}"; $lang->task->teamMember = '团队成员'; +$lang->task->addMember = '添加成员'; $lang->task->to = '至'; $lang->task->suffixHour = 'H'; diff --git a/module/task/ui/create.html.php b/module/task/ui/create.html.php index fb1c82ea44..bc71d562b6 100644 --- a/module/task/ui/create.html.php +++ b/module/task/ui/create.html.php @@ -30,6 +30,7 @@ jsVar('window.lifetimeList', $lifetimeList); jsVar('window.attributeList', $attributeList); jsVar('hasProduct', $execution->hasProduct); jsVar('hideStory', $hideStory); + $requiredFields = array(); foreach(explode(',', $config->task->create->requiredFields) as $field) { @@ -123,6 +124,136 @@ $storyPreviewBtn = span ), ); +$teamForm = array(); +for($i = 1; $i <= 3; $i ++) +{ + $teamForm[] = h::tr + ( + h::td + ( + setClass('text-center'), + set::width('40px'), + span + ( + setClass("team-number"), + $i + ), + ), + h::td + ( + set::width('240px'), + select + ( + set::name("team[$i]"), + set::items($members), + ), + ), + h::td + ( + set::width('135px'), + inputControl + ( + input + ( + set::name("teamEstimate[$i]"), + ), + to::suffix($lang->task->suffixHour), + set::suffixWidth(20), + ), + ), + h::td + ( + set::width('100px'), + setClass('center'), + btnGroup + ( + set::items(array( + array('icon' => 'plus', 'class' => 'btn btn-link', 'onclick' => 'addItem(this)'), + array('icon' => 'close', 'class' => 'btn btn-link', 'onclick' => 'removeItem(this)'), + )) + ) + ) + ); +} + +$taskTR = array(); +$i = 0; +foreach($testStories as $storyID => $storyTitle) +{ + $taskTR[] = h::tr + ( + h::td + ( + select + ( + set::id("testStory{$i}"), + set::name("testStory[$i]"), + set::value($storyID), + set::items(array($storyID => $storyTitle)), + ), + ), + h::td + ( + select + ( + set::id("testPri{$i}"), + set::name("testPri[$i]"), + set::value($task->pri), + set::items($lang->task->priList), + ), + ), + h::td + ( + input + ( + set::id("testEstStarted{$i}"), + set::name("testEstStarted[$i]"), + set::type('date'), + set::value($task->estStarted), + ), + ), + h::td + ( + input + ( + set::id("testDeadline{$i}"), + set::name("testDeadline[$i]"), + set::type('date'), + set::value($task->deadline), + ), + ), + h::td + ( + select + ( + set::id("testAssignedTo{$i}"), + set::name("testAssignedTo[$i]"), + set::value($task->assignedTo), + set::items($members), + ), + ), + h::td + ( + input + ( + set::id("testEstimate{$i}"), + set::name("testEstimate[$i]"), + ), + ), + h::td + ( + set::class('center'), + btnGroup + ( + set::items(array( + array('icon' => 'plus', 'onclick' => 'addItem(this)'), + array('icon' => 'close', 'onclick' => 'removeItem(this)'), + )) + ) + ) + ); +} + $selectStoryRow = ''; if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))) { @@ -200,8 +331,8 @@ formPanel ( formGroup ( - set::width('1/4'), set::label($lang->task->assignTo), + setClass('assignedToBox'), select ( set::id('assignedTo'), @@ -209,6 +340,24 @@ formPanel set::value($task->assignedTo), set::items($members), ), + div + ( + setClass('assignedToList'), + ), + btn + ( + set + ( + array + ( + 'class' => 'btn primary-pale hidden add-team', + 'data-toggle' => 'modal', + 'url' => '#modalTeam', + 'icon' => 'plus', + ), + ), + $lang->task->addMember, + ), ), formGroup ( @@ -219,20 +368,17 @@ formPanel set::name('multiple'), set::text($lang->task->multiple), set::rootClass('ml-4'), - on::change('showTeamBox'), + on::change('toggleTeam'), ) ), + ), + formRow + ( + setClass('hidden'), formGroup ( - set::width('1/4'), - set::class('modeBox hidden'), - radioList( - set::name('mode'), - set::value(!empty($task->mode) ? $task->mode : 'linear'), - set::class('ml-4'), - set::items($config->task->modeOptions), - set::inline(true) - ) + set::control('hidden'), + set::name('teamMember'), ) ), formRow @@ -358,7 +504,33 @@ formPanel set::name('mailto[]'), set::items($users), ), - $afterRow + $afterRow, + modalTrigger + ( + modal + ( + set::id('modalTeam'), + set::title($lang->task->teamMember), + h::table + ( + setClass('table table-form'), + $teamForm, + h::tr + ( + h::td + ( + setClass('text-center'), + set(array('colspan' => 4)), + btn + ( + setClass('btn btn-primary'), + $lang->save + ) + ) + ) + ) + ) + ) );