* @package task * @link https://www.zentao.net */ namespace zin; /* ====== Preparing and processing page data ====== */ $requiredFields = array(); foreach(explode(',', $config->task->create->requiredFields) as $field) { if($field) $requiredFields[$field] = ''; if($field && strpos($showFields, $field) === false) $showFields .= ',' . $field; } $hiddenStory = (strpos(",$showFields,", ',story,') !== false and $features['story']) ? '' : 'hidden'; $hiddenPri = strpos(",$showFields,", ',pri,') !== false ? '' : 'hidden'; $hiddenEstimate = strpos(",$showFields,", ',estimate,') !== false ? '' : 'hidden'; $hiddenEstStarted = strpos(",$showFields,", ',estStarted,') === false ? 'hidden' : ''; $hiddenDeadline = strpos(",$showFields,", ',deadline,') === false ? 'hidden' : ''; $hiddenDatePlan = (!$hiddenEstStarted || !$hiddenDeadline) ? '' : 'hidden'; $hiddenMailto = strpos(",$showFields,", ',mailto,') !== false ? '' : 'hidden'; /* zin: Set variables to define picker options for form. */ jsVar('showFields', $showFields); jsVar('toTaskList', !empty($task->id)); jsVar('blockID', $blockID); jsVar('executionID', $execution->id); jsVar('taskID', $taskID ?? 0); jsVar('ditto', $lang->task->ditto); jsVar('teamMemberError', $lang->task->error->teamMember); jsVar('vision', $config->vision); jsVar('requiredFields', $config->task->create->requiredFields); jsVar('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0')); jsVar('window.lifetime', $execution->lifetime); jsVar('window.attribute', $execution->attribute); jsVar('window.lifetimeList', $lifetimeList); jsVar('window.attributeList', $attributeList); jsVar('hasProduct', $execution->hasProduct); jsVar('hideStory', $hideStory); $executionBox = ''; /* Cannot show execution field in kanban. */ if($execution->type != 'kanban' or $this->config->vision == 'lite') { $executionBox = formGroup ( set::width('1/2'), set::name('execution'), set::label($lang->task->execution), set::value($execution->id), set::items($executions), on::change('loadAll') ); } $kanbanRow = ''; /* The region and lane fields are only showed in kanban. */ if($execution->type == 'kanban') { $kanbanRow = formRow( formGroup ( set::width('1/2'), set::label($lang->kanbancard->region), picker ( set::name('region'), set::value($regionID), set::items($regionPairs), on::change('loadLanes'), set::required(true), ) ), formGroup ( set::width('1/2'), set::label($lang->kanbancard->lane), picker ( set::name('lane'), set::value($laneID), set::items($lanePairs), set::required(true), ) ), ); } /* Set the tip when there is no story. */ if(!empty($execution->hasProduct)) { $storyEmptyPreTip = span ( setClass('input-control-prefix'), span ( $lang->task->noticeLinkStory, ), a ( set::href($this->createLink('execution', 'linkStory', "executionID=$execution->id")), setClass('text-primary'), $lang->execution->linkStory ), ); } else { $storyEmptyPreTip = span ( setClass('input-control-prefix'), span ( $lang->task->noticeLinkStory, ), ); } $storyPreviewBtn = span ( setClass('input-group-btn flex hidden'), set::id('preview'), modalTrigger ( to::trigger( btn( setClass('text-gray'), set::icon('eye'), ), ), ), ); $teamForm = array(); for($i = 1; $i <= 3; $i ++) { $teamForm[] = h::tr ( h::td ( setClass('team-index'), span ( setClass("team-number"), $i ), icon('angle-down') ), h::td ( set::width('240px'), picker ( set::name("team[]"), set::items($members), ) ), h::td ( set::width('135px'), inputControl ( input ( set::name("teamEstimate[]"), set::placeholder($lang->task->estimateAB), ), to::suffix($lang->task->suffixHour), set::suffixWidth(20), ), ), h::td ( set::width('100px'), setClass('center'), btnGroup ( set::items(array( array('icon' => 'plus', 'class' => 'btn ghost btn-add'), array('icon' => 'trash', 'class' => 'btn ghost btn-delete'), )) ) ) ); } $selectStoryRow = ''; if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))) { $selectStoryRow = formRow( set::id('testStoryBox'), setClass('hidden'), ); } $afterCreateRow = ''; /* Ct redirect within pop-ups. */ if(!isAjaxRequest('modal')) { $afterRow = formGroup ( set::width('3/4'), set::label($lang->task->afterSubmit), radioList ( set::name('after'), set::value(!empty($task->id) ? 'toTaskList' : 'continueAdding'), set::items($config->task->afterOptions), set::inline(true) ), ); } /* ====== Define the page structure with zin widgets ====== */ formPanel ( set::id('taskCreateForm'), set::title($lang->task->create), $from == 'task' ? set::customFields(true) : null, formRow ( $executionBox, formGroup ( set::width('1/2'), set::label($lang->task->module), inputGroup ( picker ( set::name('module'), set::value($task->module), set::items($modulePairs), on::change('loadExecutionStories'), ), span ( set('class', 'input-group-addon'), a ( set('id', 'showAllModuleButton'), set('href', 'javascript:;'), $lang->task->allModule, on::click('showAllModule') ), formHidden('isShowAllModule', 0), ) ) ) ), $kanbanRow, formRow ( formGroup ( set::width('1/2'), set::label($lang->task->type), set::required(true), picker ( set::name('type'), set::items($lang->task->typeList), set::value($task->type), ), on::change('typeChange') ), formGroup ( set::width('1/2'), set::id('selectTestStoryBox'), setClass('hidden items-center'), checkbox( set::id('selectTestStory'), set::name('selectTestStory'), set::value(1), set::text($lang->task->selectTestStory), set::rootClass('ml-4'), on::change('toggleSelectTestStory'), ) ), ), formRow ( formGroup ( set::label($lang->task->assignTo), setClass('assignedToBox'), picker ( set::id('assignedTo'), set::name('assignedTo[]'), set::value($task->assignedTo), set::items($members), ), btn ( set ( array ( 'class' => 'btn primary-pale hidden add-team mr-3', 'data-toggle' => 'modal', 'url' => '#modalTeam', 'icon' => 'plus', ), ), $lang->task->addMember, ), div ( setClass('assignedToList'), ), ), formGroup ( set::width('1/10'), set::id('multipleBox'), setClass('items-center'), checkbox( set::name('multiple'), set::text($lang->task->multiple), set::rootClass('ml-4'), on::change('toggleTeam'), ) ), ), formRow ( setClass('hidden'), formGroup ( set::control('hidden'), set::name('teamMember'), ) ), formRow ( setClass($hiddenStory || $hideStory ? 'hidden' : ''), formGroup ( set::label($lang->task->story), setClass(empty($stories) ? 'hidden' : ''), inputGroup ( picker ( set::id('story'), set::name('story'), set::value($task->story), set::items(array_filter($stories)), on::change('setStoryRelated'), ), $storyPreviewBtn, ) ), formGroup ( set::label($lang->task->story), setClass(!empty($stories) ? 'hidden' : ''), div ( setClass('empty-story-tip input-control has-prefix has-suffix'), $storyEmptyPreTip, input( set::name(''), set('readonly'), set('onfocus', 'this.blur()'), ), span ( setClass('input-control-suffix'), btn( setClass('text-gray'), set::id('refreshStories'), set::icon('refresh'), on::click('loadExecutionStories'), ) ), ), ), ), $selectStoryRow, formRow ( formGroup ( set::width('4/5'), set::label($lang->task->name), set::strong(true), set::required(true), inputControl ( input ( set::name('name'), set::value($task->name), ), to::suffix ( colorPicker ( set::heading($lang->task->colorTag), set::name('color'), set::value($task->color), set::syncColor('#name') ), checkbox( set::id('copyButton'), set::name('copyButton'), set::value(1), set::text($lang->task->copyStoryTitle), set::rootClass('ml-2 border-l border-gray pl-2'), on::change('copyStoryTitle') ), ), ), formHidden('storyEstimate', ''), formHidden('storyDesc', ''), formHidden('storyPri', 0), ), formGroup ( set::width('1/5'), setClass('no-background'), inputGroup ( span ( setClass("input-group-addon {$hiddenPri}"), $lang->task->pri, ), priPicker ( setClass($hiddenPri), set::name('pri'), set::value('3'), set::items(array_filter($lang->task->priList)), ), span ( setClass("input-group-addon {$hiddenEstimate}"), $lang->task->estimateAB ), inputControl ( set::className($hiddenEstimate), input(set::name('estimate')), to::suffix ( $lang->task->suffixHour ), set::suffixWidth(20), ), ), ), ), formGroup ( set::label($lang->task->desc), editor ( set::name('desc'), set::rows('5'), ) ), formGroup ( set::label($lang->story->files), upload() ), formGroup ( set::width('1/2'), set::label($lang->task->datePlan), setClass($hiddenDatePlan), inputGroup ( datepicker ( setClass($hiddenEstStarted), set::control('date'), set::name('estStarted'), set::value($task->estStarted), set::placeholder($lang->task->estStarted), ), span ( setClass('input-group-addon'), setClass($hiddenEstStarted || $hiddenDeadline ? 'hidden' : ''), $lang->task->to, ), datepicker ( setClass($hiddenDeadline), set::control('date'), set::name('deadline'), set::value($task->deadline), set::placeholder($lang->task->deadline), ), ) ), formGroup ( setClass($hiddenMailto), set::label($lang->product->mailto), picker ( set::multiple(true), set::name('mailto[]'), set::items($users), ) ), $afterRow, modalTrigger ( modal ( set::id('modalTeam'), set::title($lang->task->teamMember), h::table ( set::id('teamTable'), h::tr ( h::td ( width('90px'), $lang->task->mode ), h::td ( picker ( set::name("mode"), set::value("linear"), set::items($lang->task->modeList), set::required(true), ), ) ), setClass('table table-form'), $teamForm, h::tr ( h::td ( setClass('team-saveBtn'), set(array('colspan' => 4)), btn ( setClass('toolbar-item btn primary'), $lang->save ) ) ) ) ) ) ); /* ====== Render page ====== */ render();