Merge branch 'master' into story
This commit is contained in:
@@ -38,6 +38,8 @@ div
|
||||
common::hasPriv('execution', 'burn') ? echarts
|
||||
(
|
||||
set::grid(array('left' => '0', 'right' => '50px', 'bottom' => '0', 'containLabel' => true)),
|
||||
set::width('100%'),
|
||||
set::height('150%'),
|
||||
set::xAxis
|
||||
(
|
||||
array
|
||||
@@ -167,7 +169,7 @@ div
|
||||
) : null
|
||||
)
|
||||
)
|
||||
)->size('100%', '150%') : null
|
||||
) : null
|
||||
);
|
||||
|
||||
/* ====== Render page ====== */
|
||||
|
||||
@@ -38,6 +38,8 @@ if(hasPriv('execution', 'cfd'))
|
||||
$cfdChart = isset($chartData['labels']) && count($chartData['labels']) != 1 ? echarts
|
||||
(
|
||||
set::series($chartSeries),
|
||||
set::width('100%'),
|
||||
set::height('150%'),
|
||||
set::tooltip(array(
|
||||
'trigger' => 'axis',
|
||||
'axisPointer' => array('type' => 'cross', 'label' => array('backgroundColor' => '#6a7985')),
|
||||
@@ -65,7 +67,7 @@ if(hasPriv('execution', 'cfd'))
|
||||
'axisPointer' => array('label' => array('show' => true, 'precision' => 0)),
|
||||
'axisLine' => array('show' => true, 'lineStyle' => array('color' => '#999', 'width' => 1))
|
||||
)))
|
||||
)->size('100%', '150%') : div
|
||||
) : div
|
||||
(
|
||||
setClass('table-empty-tip text-center'),
|
||||
span
|
||||
|
||||
@@ -17,9 +17,8 @@ if(empty($executions))
|
||||
{
|
||||
$executionsBox[] = div
|
||||
(
|
||||
setClass('inline-flex items-center'),
|
||||
setClass('alert with-icon w-full'),
|
||||
icon('exclamation-sign text-gray icon-2x pl-2 text-warning'),
|
||||
setClass('inline-flex items-center with-icon w-full bg-gray-100 py-4'),
|
||||
icon('exclamation-sign icon-2x pl-2 text-warning'),
|
||||
span
|
||||
(
|
||||
set::className('font-bold ml-2'),
|
||||
@@ -42,7 +41,7 @@ else
|
||||
setClass('text-gray'),
|
||||
$lang->icons[$execution->type]
|
||||
),
|
||||
span($execution->name)
|
||||
span(setClass('text-left'), $execution->name)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ formBatchPanel
|
||||
formBatchItem
|
||||
(
|
||||
set::name('name'),
|
||||
set::label($lang->execution->name),
|
||||
set::label($app->tab == 'execution' ? $lang->execution->execName : $lang->execution->name),
|
||||
set::width('240px'),
|
||||
set::required(true)
|
||||
),
|
||||
@@ -72,14 +72,14 @@ formBatchPanel
|
||||
$setCode ? formBatchItem
|
||||
(
|
||||
set::name('code'),
|
||||
set::label($lang->execution->code),
|
||||
set::label($app->tab == 'execution' ? $lang->execution->execCode : $lang->execution->code),
|
||||
set::width('136px'),
|
||||
set::required(strpos(",{$config->execution->edit->requiredFields},", ',code,') !== false)
|
||||
) : null,
|
||||
formBatchItem
|
||||
(
|
||||
set::name('PM'),
|
||||
set::label($lang->execution->PM),
|
||||
set::label($app->tab == 'execution' ? $lang->execution->execPM : $lang->execution->PM),
|
||||
set::control('picker'),
|
||||
set::ditto(true),
|
||||
set::defaultDitto('off'),
|
||||
@@ -123,9 +123,7 @@ formBatchPanel
|
||||
formBatchItem
|
||||
(
|
||||
set::name('lifetime'),
|
||||
set::label(
|
||||
$lang->execution->type
|
||||
),
|
||||
set::label($app->tab == 'execution' ? $lang->execution->execType : $lang->execution->type),
|
||||
set::control('picker'),
|
||||
set::items($lang->execution->lifeTimeList),
|
||||
set::width('120px'),
|
||||
@@ -171,7 +169,7 @@ formBatchPanel
|
||||
formBatchItem
|
||||
(
|
||||
set::name('desc'),
|
||||
set::label($lang->execution->desc),
|
||||
set::label($app->tab == 'execution' ? $lang->execution->execDesc : $lang->execution->desc),
|
||||
set::control('textarea'),
|
||||
set::width('160px'),
|
||||
set::hidden(strpos("{$showFields}", 'desc') === false)
|
||||
|
||||
@@ -26,7 +26,7 @@ if($canExportBug) $exportItem = array
|
||||
(
|
||||
'icon' => 'export',
|
||||
'class' => 'ghost',
|
||||
'text' => $lang->bug->export,
|
||||
'text' => $lang->export,
|
||||
'data-toggle' => 'modal',
|
||||
'url' => $this->createLink('bug', 'export', "productID={$productID}&browseType=&executionID={$execution->id}")
|
||||
);
|
||||
@@ -78,6 +78,12 @@ if(isset($cols['module'])) $cols['module']['map'] = $modulePairs;
|
||||
if(isset($cols['branch'])) $cols['branch']['map'] = $branchOption;
|
||||
if(isset($cols['project'])) $cols['project']['map'] = $projectPairs;
|
||||
if(isset($cols['openedBuild'])) $cols['openedBuild']['map'] = $builds;
|
||||
if(isset($cols['plan'])) $cols['plan']['map'] = array('') + $plans;
|
||||
if(isset($cols['task'])) $cols['task']['map'] = array('') + $tasks;
|
||||
if(isset($cols['toTask'])) $cols['toTask']['map'] = array('') + $tasks;
|
||||
if(isset($cols['story'])) $cols['story']['map'] = array('') + $stories;
|
||||
|
||||
if(isset($cols['activatedCount'])) $cols['activatedCount']['map'] = array('');
|
||||
|
||||
$bugs = initTableData($bugs, $cols, $this->execution);
|
||||
|
||||
@@ -86,6 +92,8 @@ dtable
|
||||
set::userMap($users),
|
||||
set::cols($cols),
|
||||
set::data(array_values($bugs)),
|
||||
set::priList($lang->bug->priList),
|
||||
set::severityList($lang->bug->severityList),
|
||||
set::checkable($canBatchAssignTo),
|
||||
set::orderBy($orderBy),
|
||||
set::sortLink(createLink('execution', 'bug', "executionID={$execution->id}&productID={$productID}&branch={$branchID}&orderBy={name}_{sortType}&build=$buildID&type=$type¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}")),
|
||||
|
||||
@@ -35,10 +35,7 @@ featureBar
|
||||
/* zin: Define the toolbar on main menu. */
|
||||
$canCreateBuild = hasPriv('build', 'create') && common::canModify('execution', $execution);
|
||||
if($canCreateBuild) $createItem = array('icon' => 'plus', 'class' => 'primary', 'text' => $lang->build->create, 'url' => $this->createLink('build', 'create', "executionID={$execution->id}"));
|
||||
toolbar
|
||||
(
|
||||
!empty($createItem) ? item(set($createItem)) : null,
|
||||
);
|
||||
toolbar(!empty($createItem) ? item(set($createItem)) : null);
|
||||
|
||||
jsVar('executionID', $execution->id);
|
||||
jsVar('changeProductLink', helper::createLink('execution', 'build', "executionID={$execution->id}&type=product¶m={productID}&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"));
|
||||
@@ -47,28 +44,25 @@ jsVar('filePathTip', $lang->build->filePath);
|
||||
jsVar('confirmDelete', $lang->build->confirmDelete);
|
||||
|
||||
$fieldList = $config->build->dtable->fieldList;
|
||||
if($execution->type == 'kanban') unset($fieldList['actions']['actionsMap']['createTest']['data-app']);
|
||||
if($execution->type == 'kanban')
|
||||
{
|
||||
unset($fieldList['actions']['list']['createTest']['data-app']);
|
||||
$fieldList['actions']['list']['viewBug']['url'] = $config->build->actionList['bugList']['url'];
|
||||
}
|
||||
$builds = initTableData($builds, $fieldList, $this->build);
|
||||
|
||||
dtable
|
||||
(
|
||||
set::userMap($users),
|
||||
set::cols($fieldList),
|
||||
set::data($builds),
|
||||
set::plugins(array('cellspan')),
|
||||
set::userMap($users),
|
||||
set::onRenderCell(jsRaw('window.renderCell')),
|
||||
set::getCellSpan(jsRaw('window.getCellSpan')),
|
||||
set::orderBy($orderBy),
|
||||
set::sortLink(createLink('execution', 'build', "executionID={$execution->id}&type={$type}¶m={$param}&orderBy={name}_{sortType}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}")),
|
||||
set::getCellSpan(jsRaw('window.getCellSpan')),
|
||||
set::footPager(
|
||||
usePager
|
||||
(
|
||||
array('linkCreator' => helper::createLink('execution', 'build', "executionID={$execution->id}&type={$type}¶m={$param}&orderBy={$orderBy}&recTotal={recTotal}&recPerPage={page}"), 'recTotal' => $pager->recTotal, 'recPerPage' => $pager->recPerPage)
|
||||
)
|
||||
),
|
||||
set::footPager(usePager()),
|
||||
set::emptyTip($lang->build->noBuild),
|
||||
set::createTip($lang->build->create),
|
||||
set::createLink($canCreateBuild ? createLink('build', 'create', "executionID={$execution->id}") : '')
|
||||
);
|
||||
|
||||
/* ====== Render page ====== */
|
||||
render();
|
||||
|
||||
@@ -127,6 +127,8 @@ panel
|
||||
),
|
||||
echarts
|
||||
(
|
||||
set::height(500),
|
||||
set::exts('timeline'),
|
||||
set::xAxis
|
||||
(
|
||||
array
|
||||
@@ -261,5 +263,5 @@ panel
|
||||
) : null
|
||||
)
|
||||
)
|
||||
)->size('100%', 500),
|
||||
)
|
||||
);
|
||||
|
||||
@@ -116,6 +116,8 @@ if(isset($chartData['labels']) and count($chartData['labels']) != 1)
|
||||
$cfdChart = echarts
|
||||
(
|
||||
set::series($chartSeries),
|
||||
set::width('100%'),
|
||||
set::height(500),
|
||||
set::tooltip(array(
|
||||
'trigger' => 'axis',
|
||||
'axisPointer' => array('type' => 'cross', 'label' => array('backgroundColor' => '#6a7985')),
|
||||
@@ -146,7 +148,7 @@ if(isset($chartData['labels']) and count($chartData['labels']) != 1)
|
||||
'axisPointer' => array('label' => array('show' => true, 'precision' => 0)),
|
||||
'axisLine' => array('show' => true, 'lineStyle' => array('color' => '#999', 'width' => 1))
|
||||
)))
|
||||
)->size('100%', 500);
|
||||
);
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -17,9 +17,9 @@ $fields->field('project')
|
||||
->items(data('allProjects'))
|
||||
->value(data('projectID'));
|
||||
|
||||
if(!empty($project->model) && $project->model == 'agileplus')
|
||||
if(!empty($project->model) and in_array($project->model, array('agileplus', 'ipd', 'waterfallplus')))
|
||||
{
|
||||
unset($lang->execution->typeList['stage'], $lang->execution->typeList['']);
|
||||
if($project->model == 'agileplus' ) unset($lang->execution->typeList['stage'], $lang->execution->typeList['']);
|
||||
$fields->field('method')
|
||||
->required()
|
||||
->name('type')
|
||||
@@ -42,7 +42,7 @@ $fields->field('code')
|
||||
|
||||
$fields->field('type')
|
||||
->required()
|
||||
->control('checkBtnGroup')
|
||||
->control($isStage ? 'picker' : 'checkBtnGroup')
|
||||
->label($showExecutionExec ? $lang->execution->execType : $lang->execution->type)
|
||||
->name($isStage ? 'attribute' : 'lifetime')
|
||||
->hidden($isKanban)
|
||||
@@ -89,6 +89,7 @@ $fields->field('productsBox')
|
||||
'project' => data('project'),
|
||||
'isStage' => data('isStage'),
|
||||
'errorSameProducts' => $lang->execution->errorSameProducts,
|
||||
'from' => 'execution'
|
||||
));
|
||||
|
||||
$fields->field('desc')
|
||||
@@ -99,7 +100,7 @@ $fields->field('desc')
|
||||
|
||||
$fields->field('PO')->foldable()->required(strpos($requiredFields, ",PO,") !== false)->items(data('poUsers'))->value(data('execution.PO'));
|
||||
$fields->field('QD')->foldable()->required(strpos($requiredFields, ",QD,") !== false)->items(data('qdUsers'))->value(data('execution.QD'));
|
||||
$fields->field('PM')->foldable()->required(strpos($requiredFields, ",PM,") !== false)->items(data('pmUsers'))->value(data('execution.PM'));
|
||||
$fields->field('PM')->foldable()->required(strpos($requiredFields, ",PM,") !== false)->items(data('pmUsers'))->value(data('execution.PM'))->label($showExecutionExec ? $lang->execution->execPM : $lang->execution->PM);
|
||||
$fields->field('RD')->foldable()->required(strpos($requiredFields, ",RD,") !== false)->items(data('rdUsers'))->value(data('execution.RD'));
|
||||
|
||||
$fields->field('teamName')
|
||||
|
||||
@@ -46,6 +46,7 @@ jsVar('weekend', $config->execution->weekend);
|
||||
jsVar('isStage', $isStage);
|
||||
jsVar('copyExecutionID', $copyExecutionID);
|
||||
jsVar('executionID', isset($executionID) ? $executionID : 0);
|
||||
jsVar('typeDesc', $lang->execution->typeDesc);
|
||||
|
||||
$showExecutionExec = !empty($from) and ($from == 'execution' || $from == 'doc');
|
||||
|
||||
@@ -58,7 +59,7 @@ $handleBeginEndChange = jsCallback()
|
||||
if(!zui.isValidDate(begin) || !zui.isValidDate(end)) return;
|
||||
const $days = $element.find('[name=days]');
|
||||
const beginDate = zui.createDate(begin);
|
||||
const endDate = zui.createDate(end);
|
||||
const endDate = zui.createDate(end);
|
||||
const totalDays = 1 + Math.ceil((endDate.getTime() - beginDate.getTime()) / zui.TIME_DAY);
|
||||
if(totalDays <= 0) return $days.val(0);
|
||||
let workDays = 0;
|
||||
@@ -82,8 +83,8 @@ formGridPanel
|
||||
(
|
||||
set::icon('copy'),
|
||||
setClass('primary-ghost size-md'),
|
||||
toggle::modal(array('target' => '#copyExecutionModal', 'destoryOnHide' => true)),
|
||||
$lang->execution->copy
|
||||
toggle::modal(array('target' => '#copyExecutionModal', 'destoryOnHide' => true, 'size' => 'sm')),
|
||||
$lang->execution->copyExec
|
||||
),
|
||||
divider(setClass('h-4 mr-4 ml-2 self-center'))
|
||||
),
|
||||
@@ -92,6 +93,7 @@ formGridPanel
|
||||
on::change('[name=begin],[name=end]', $handleBeginEndChange),
|
||||
on::change('[name=teams]', 'loadMembers'),
|
||||
on::change('#copyTeam', 'toggleCopyTeam'),
|
||||
on::click('[name=lifetime]', 'toggleOpsTip'),
|
||||
set::fields($fields)
|
||||
);
|
||||
|
||||
@@ -103,37 +105,51 @@ modalTrigger
|
||||
set::footerClass('justify-center'),
|
||||
to::header
|
||||
(
|
||||
span
|
||||
div
|
||||
(
|
||||
h4
|
||||
setClass('w-full'),
|
||||
div
|
||||
(
|
||||
set::className('copy-title'),
|
||||
$lang->execution->copyTitle
|
||||
h4
|
||||
(
|
||||
set::className('copy-title'),
|
||||
$lang->execution->copyTitle
|
||||
)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('flex items-center py-4 border-b border-b-1'),
|
||||
span
|
||||
(
|
||||
setClass('mr-2'),
|
||||
$lang->execution->selectProject
|
||||
),
|
||||
picker
|
||||
(
|
||||
set::className('flex-1 w-full'),
|
||||
set::name('project'),
|
||||
set::items($copyProjects),
|
||||
set::value($projectID),
|
||||
set::required(true),
|
||||
on::change('loadProjectExecutions')
|
||||
)
|
||||
)
|
||||
),
|
||||
picker
|
||||
(
|
||||
set::className('pickerProject'),
|
||||
set::name('project'),
|
||||
set::items($copyProjects),
|
||||
set::value($projectID),
|
||||
set::required(true),
|
||||
on::change('loadProjectExecutions')
|
||||
)
|
||||
),
|
||||
to::footer
|
||||
(
|
||||
setClass('mt-4'),
|
||||
btn
|
||||
(
|
||||
setClass('primary btn-wide hidden confirmBtn'),
|
||||
set::text($lang->execution->copy),
|
||||
set::text($lang->execution->copyExec),
|
||||
on::click('setCopyExecution')
|
||||
)
|
||||
),
|
||||
div
|
||||
(
|
||||
set::id('copyExecutions'),
|
||||
setClass('flex items-center flex-wrap')
|
||||
setClass('flex items-center flex-wrap gap-4')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ if($project)
|
||||
}
|
||||
elseif($project->model == 'agileplus')
|
||||
{
|
||||
$fields->field('project')
|
||||
$fields->field('type')
|
||||
->label($lang->execution->method)
|
||||
->disabled()
|
||||
->value(zget($lang->execution->typeList, data('execution.type')));
|
||||
@@ -86,14 +86,12 @@ $fields->field('name')
|
||||
->value(data('execution.name'))
|
||||
->wrapAfter(empty($config->setCode) && $project->model == 'ipd');
|
||||
|
||||
if(!empty($config->setCode))
|
||||
{
|
||||
$fields->field('code')
|
||||
->label($lang->execution->code)
|
||||
->value(data('execution.code'))
|
||||
->required(in_array('code', explode(',', $config->execution->edit->requiredFields)))
|
||||
->width('1/4');
|
||||
}
|
||||
$fields->field('code')
|
||||
->label($lang->execution->code)
|
||||
->value(data('execution.code'))
|
||||
->hidden(empty($config->setCode))
|
||||
->required(in_array('code', explode(',', $config->execution->edit->requiredFields)))
|
||||
->width('1/4');
|
||||
|
||||
if($project && $project->model != 'ipd')
|
||||
{
|
||||
@@ -125,7 +123,7 @@ $fields->field('days')
|
||||
->value(data('execution.days'))
|
||||
->width($hasPercent ? '1/4' : '1/2');
|
||||
|
||||
if($hasPercent)
|
||||
if($hasPercent && $project && $project->model != 'ipd')
|
||||
{
|
||||
$fields->field('percent')
|
||||
->label($lang->stage->percent)
|
||||
@@ -144,10 +142,12 @@ $fields->field('productsBox')
|
||||
'planGroups' => data('productPlans'),
|
||||
'linkedProducts' => data('linkedProducts'),
|
||||
'linkedBranches' => data('linkedBranches'),
|
||||
'productPlans' => data('productPlans'),
|
||||
'productPlans' => data('productPlan'),
|
||||
'currentPlan' => data('currentPlan'),
|
||||
'project' => data('project'),
|
||||
'isStage' => isset($project->model) && in_array($project->model, array('waterfall', 'waterfallplus')),
|
||||
'errorSameProducts' => $lang->execution->errorSameProducts,
|
||||
'from' => 'execution'
|
||||
));
|
||||
|
||||
$fields->field('PO')
|
||||
|
||||
@@ -35,11 +35,32 @@ foreach($kanbanList as $current => $region)
|
||||
|
||||
jsVar('privs', $privs);
|
||||
jsVar('delayed', $lang->project->statusList['delay']);
|
||||
zui::kanbanList
|
||||
(
|
||||
set::key('kanban'),
|
||||
set::items($kanbanList),
|
||||
set::height('calc(100vh - 120px)')
|
||||
);
|
||||
|
||||
render();
|
||||
if(empty($kanbanList))
|
||||
{
|
||||
panel
|
||||
(
|
||||
div
|
||||
(
|
||||
setClass('dtable-empty-tip'),
|
||||
div
|
||||
(
|
||||
setClass('row gap-4 items-center'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->noData
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
zui::kanbanList
|
||||
(
|
||||
set::key('kanban'),
|
||||
set::items($kanbanList),
|
||||
set::height('calc(100vh - 120px)')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ if(isset($lang->execution->groupFilter[$groupBy]))
|
||||
($filterKey == $filter) ? set('class', 'active') : null,
|
||||
span(setClass('text'), $name),
|
||||
($filterKey == $filter) ? span(setClass('label size-sm rounded-full white'), $allCount) : null,
|
||||
set::href(createLink('execution', 'grouptask', "executionID={$executionID}&groupBy={$groupBy}&filter={$filterKey}"))
|
||||
set::href(createLink('execution', 'grouptask', "executionID={$executionID}&groupBy={$groupBy}&filter={$filterKey}")),
|
||||
set('data-app', $app->tab)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -38,7 +39,8 @@ else
|
||||
set('class', 'active'),
|
||||
span(setClass('text'), $lang->all),
|
||||
span(setClass('label size-sm rounded-full white'), $allCount),
|
||||
set::href(createLink('execution', 'grouptask', "executionID={$executionID}&groupBy={$groupBy}"))
|
||||
set::href(createLink('execution', 'grouptask', "executionID={$executionID}&groupBy={$groupBy}")),
|
||||
set('data-app', $app->tab)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -73,7 +75,7 @@ $canImportTask = hasPriv('task', 'importTask');
|
||||
$canImportBug = hasPriv('task', 'importBug');
|
||||
if(common::canModify('execution', $execution))
|
||||
{
|
||||
$createLink = $this->createLink('task', 'create', "executionID={$execution->id}" . ($app->tab == 'project' ? '#app=project' : ''));
|
||||
$createLink = $this->createLink('task', 'create', "executionID={$execution->id}") . ($app->tab == 'project' ? '#app=project' : '');
|
||||
if(commonModel::isTutorialMode())
|
||||
{
|
||||
$wizardParams = helper::safe64Encode("executionID={$execution->id}");
|
||||
@@ -97,10 +99,11 @@ toolbar
|
||||
(
|
||||
hasPriv('task', 'report') ? item(set(array
|
||||
(
|
||||
'text' => $lang->task->report->common,
|
||||
'icon' => 'bar-chart',
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('task', 'report', "execution={$execution->id}&browseType={$browseType}")
|
||||
'text' => $lang->task->report->common,
|
||||
'icon' => 'bar-chart',
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('task', 'report', "execution={$execution->id}&browseType={$browseType}"),
|
||||
'data-app' => $app->tab
|
||||
))) : null,
|
||||
hasPriv('task', 'export') ? item(set(array
|
||||
(
|
||||
@@ -120,7 +123,7 @@ toolbar
|
||||
set::items($importItems),
|
||||
set::placement('bottom-end')
|
||||
) : null,
|
||||
$canCreate ? item(set($createItem + array('class' => 'btn primary', 'icon' => 'plus'))) : null
|
||||
$canCreate && isset($createItem) ? item(set($createItem + array('class' => 'btn primary', 'icon' => 'plus'))) : null
|
||||
);
|
||||
|
||||
$groupList = array();
|
||||
@@ -128,9 +131,11 @@ foreach($lang->execution->groups as $key => $value)
|
||||
{
|
||||
if(empty($key)) continue;
|
||||
$link = createLink('execution', 'grouptask', "executionID={$executionID}&groupBy={$key}");
|
||||
$groupList[] = array(
|
||||
'text' => $value,
|
||||
'url' => $link
|
||||
$groupList[] = array
|
||||
(
|
||||
'text' => $value,
|
||||
'url' => $link,
|
||||
'data-app' => $app->tab
|
||||
);
|
||||
}
|
||||
|
||||
@@ -274,7 +279,6 @@ $tbody = function() use($tasks, $lang, $groupBy, $users, $groupByList, $executio
|
||||
foreach($groupTasks as $task)
|
||||
{
|
||||
$assignedToStyle = $task->assignedTo == $app->user->account ? "style='color:red'" : '';
|
||||
$taskLink = $this->createLink('task','view',"taskID=$task->id");
|
||||
|
||||
$tbody[] = h::tr
|
||||
(
|
||||
@@ -318,7 +322,7 @@ $tbody = function() use($tasks, $lang, $groupBy, $users, $groupByList, $executio
|
||||
!empty($task->mode) ? span(setClass('label gray-pale rounded-xl'), $lang->task->multipleAB) : null,
|
||||
$task->parent > 0 ? span(setClass('label gray-pale rounded-xl'), $lang->task->childrenAB) : null,
|
||||
(isset($task->children) && $task->children == true) ? span(setClass('label gray-pale rounded-xl'), $lang->task->parentAB) : null,
|
||||
a(set::href(createLink('task', 'view', "task=$task->id")), $task->name)
|
||||
a(set::href(createLink('task', 'view', "task=$task->id")), $task->name, set('data-app', $app->tab))
|
||||
),
|
||||
h::td
|
||||
(
|
||||
@@ -397,9 +401,10 @@ $tbody = function() use($tasks, $lang, $groupBy, $users, $groupByList, $executio
|
||||
(
|
||||
array
|
||||
(
|
||||
'url' => createLink('task', 'edit', "taskID=$task->id"),
|
||||
'class' => 'btn ghost toolbar-item text-primary square size-sm',
|
||||
'icon' => 'edit'
|
||||
'url' => createLink('task', 'edit', "taskID=$task->id"),
|
||||
'class' => 'btn ghost toolbar-item text-primary square size-sm',
|
||||
'icon' => 'edit',
|
||||
'data-app' => $app->tab
|
||||
)
|
||||
)
|
||||
) : null,
|
||||
@@ -511,7 +516,7 @@ else
|
||||
(
|
||||
set::text($lang->task->create),
|
||||
set::icon('plus'),
|
||||
set::url(createLink('task', 'create', "execution={$executionID}" . (isset($moduleID) ? "&storyID=&moduleID={$moduleID}" : '' . ($app->tab == 'project' ? '#app=project' : '')))),
|
||||
set::url(createLink('task', 'create', "execution={$executionID}" . (isset($moduleID) ? "&storyID=&moduleID={$moduleID}" : '')) . ($app->tab == 'project' ? '#app=project' : '')),
|
||||
setClass('btn primary-pale border-primary ml-2')
|
||||
) : null
|
||||
)
|
||||
|
||||
@@ -29,7 +29,8 @@ if(!isInModal())
|
||||
'text' => $lang->goback,
|
||||
'className' => 'btn btn-info size-sm text-gray',
|
||||
'url' => createLink('execution', 'task', "executionID={$execution->id}"),
|
||||
'btnType' => 'info'
|
||||
'btnType' => 'info',
|
||||
'data-app' => $app->tab
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@ featureBar
|
||||
(
|
||||
set::current('all'),
|
||||
set::linkParams("toExecution={$execution->id}"),
|
||||
btn
|
||||
inputGroup
|
||||
(
|
||||
set::text($lang->execution->selectExecution),
|
||||
setClass('ml-6')
|
||||
),
|
||||
picker
|
||||
(
|
||||
set::width(200),
|
||||
set::name('execution'),
|
||||
set::items($executions),
|
||||
set::value($fromExecution),
|
||||
set::required(true),
|
||||
on::change('changeExecution')
|
||||
setClass('ml-6'),
|
||||
$lang->execution->selectExecution,
|
||||
picker
|
||||
(
|
||||
set::width(200),
|
||||
set::name('execution'),
|
||||
set::items($executions),
|
||||
set::value($fromExecution),
|
||||
set::required(true),
|
||||
on::change('changeExecution')
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -54,17 +54,17 @@ if($this->execution->isClickable($execution, 'delete')) $operationMenu[] = arr
|
||||
|
||||
$canCreateTask = common::hasPriv('task', 'create') && common::canModify('execution', $execution);
|
||||
$canBatchCreateTask = common::hasPriv('task', 'batchCreate') && common::canModify('execution', $execution);
|
||||
$canImportTask = common::hasPriv('execution', 'importTask') && $execution->multiple && common::canModify('execution', $execution);
|
||||
$canImportTask = common::hasPriv('execution', 'importTask') && $execution->multiple && common::canModify('execution', $execution) && $this->config->vision != 'lite';
|
||||
|
||||
$canCreateBug = $features['qa'] && common::hasPriv('bug', 'create') && common::canModify('execution', $execution) && $productID;
|
||||
$canBatchCreateBug = $features['qa'] && common::hasPriv('bug', 'batchCreate') && $execution->multiple && common::canModify('execution', $execution) && $productID;
|
||||
$canImportBug = $features['qa'] && common::hasPriv('execution', 'importBug') && $execution->multiple && common::canModify('execution', $execution) && $productID;
|
||||
$canCreateBug = $features['qa'] && common::hasPriv('bug', 'create') && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$canBatchCreateBug = $features['qa'] && common::hasPriv('bug', 'batchCreate') && $execution->multiple && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$canImportBug = $features['qa'] && common::hasPriv('execution', 'importBug') && $execution->multiple && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$hasBugButton = $features['qa'] && ($canCreateBug || $canBatchCreateBug);
|
||||
|
||||
$canCreateStory = $features['story'] && common::hasPriv('story', 'create') && common::canModify('execution', $execution) && $productID;
|
||||
$canBatchCreateStory = $features['story'] && common::hasPriv('story', 'batchCreate') && common::canModify('execution', $execution) && $productID;
|
||||
$canLinkStory = $features['story'] && common::hasPriv('execution', 'linkStory') && !empty($execution->hasProduct) && common::canModify('execution', $execution) && $productID;
|
||||
$canLinkStoryByPlan = $features['story'] && common::hasPriv('execution', 'importplanstories') && !empty($project->hasProduct) && common::canModify('execution', $execution) && $productID;
|
||||
$canCreateStory = $features['story'] && common::hasPriv('story', 'create') && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$canBatchCreateStory = $features['story'] && common::hasPriv('story', 'batchCreate') && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$canLinkStory = $features['story'] && common::hasPriv('execution', 'linkStory') && !empty($execution->hasProduct) && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$canLinkStoryByPlan = $features['story'] && common::hasPriv('execution', 'importplanstories') && !empty($project->hasProduct) && common::canModify('execution', $execution) && $productID && $this->config->vision != 'lite';
|
||||
$hasStoryButton = $features['story'] && ($canCreateStory || $canBatchCreateStory || $canLinkStory || $canLinkStoryByPlan);
|
||||
|
||||
$hasTaskButton = $canCreateTask || $canBatchCreateTask || $canImportBug;
|
||||
@@ -91,7 +91,7 @@ if($canBatchCreateBug)
|
||||
if(($hasStoryButton or $hasBugButton) and $hasTaskButton) $createMenu[] = array('type' => 'divider');
|
||||
if($canCreateTask) $createMenu[] = array('text' => $lang->task->create, 'url' => helper::createLink('task', 'create', "execution=$execution->id"), 'data-toggle' => 'modal', 'data-size' => 'lg');
|
||||
if($canImportBug) $createMenu[] = array('text' => $lang->execution->importBug, 'url' => helper::createLink('execution', 'importBug', "execution=$execution->id"), 'data-toggle' => 'modal');
|
||||
if($canImportTask) $createMenu[] = array('text' => $lang->execution->importTask, 'url' => helper::createLink('execution', 'importTask', "execution=$execution->id"), 'data-toggle' => 'modal');
|
||||
if($canImportTask) $createMenu[] = array('text' => $lang->execution->importTask, 'url' => helper::createLink('execution', 'importTask', "execution=$execution->id"));
|
||||
if($canBatchCreateTask) $createMenu[] = array('text' => $lang->execution->batchCreateTask, 'url' => helper::createLink('task', 'batchCreate', "execution=$execution->id"), 'data-toggle' => 'modal', 'data-size' => 'lg');
|
||||
|
||||
jsVar('laneCount', $laneCount);
|
||||
@@ -156,9 +156,17 @@ jsVar('priv',
|
||||
|
||||
if(!$features['story']) unset($lang->kanban->type['story']);
|
||||
if(!$features['qa']) unset($lang->kanban->type['bug']);
|
||||
|
||||
$executionItems = array();
|
||||
foreach($executionList as $childExecution) $executionItems[] = array('text' => $childExecution->name, 'url' => createLink('execution', 'kanban', "kanbanID={$childExecution->id}"));
|
||||
featureBar
|
||||
(
|
||||
($features['story'] or $features['qa']) ? inputControl
|
||||
$this->config->vision == 'lite' ? dropdown
|
||||
(
|
||||
btn(setClass('dropdown-btn'), $execution->name),
|
||||
set::items($executionItems),
|
||||
) : null,
|
||||
(($features['story'] or $features['qa']) && $this->config->vision != 'lite') ? inputControl
|
||||
(
|
||||
setClass('c-type'),
|
||||
picker
|
||||
@@ -171,7 +179,7 @@ featureBar
|
||||
set::onchange('changeBrowseType()'),
|
||||
)
|
||||
) : null,
|
||||
$browseType != 'all' ? inputControl
|
||||
$browseType != 'all' && $this->config->vision != 'lite' ? inputControl
|
||||
(
|
||||
setClass('c-group ml-5'),
|
||||
picker
|
||||
@@ -293,7 +301,6 @@ modal
|
||||
(
|
||||
setID('linkStoryByPlan'),
|
||||
setData('size', '500px'),
|
||||
setID('linkStoryByPlan'),
|
||||
set::modalProps(array('title' => $lang->execution->linkStoryByPlan)),
|
||||
div
|
||||
(
|
||||
@@ -347,7 +354,7 @@ modal
|
||||
(
|
||||
setClass('primary'),
|
||||
setID('batchCreateStoryButton'),
|
||||
set::url(createLink('story', 'batchCreate', 'productID=' . key($productNames) . '&branch=moduleID=0&storyID=0&executionID=' . $executionID)),
|
||||
set::url(createLink('story', 'batchCreate', 'productID=' . key($productNames) . '&branch=0&moduleID=0&storyID=0&executionID=' . $executionID)),
|
||||
set('data-toggle', 'modal'),
|
||||
set('data-dismiss', 'modal'),
|
||||
set('data-size', 'lg'),
|
||||
|
||||
@@ -12,6 +12,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace zin;
|
||||
|
||||
data('activeMenuID', $storyType);
|
||||
|
||||
featureBar(li
|
||||
(
|
||||
setClass('nav-item'),
|
||||
@@ -29,6 +31,8 @@ searchForm
|
||||
$cols = $config->execution->linkStory->dtable->fieldList;
|
||||
$cols['module']['map'] = $modules;
|
||||
$cols['product']['map'] = $productPairs;
|
||||
|
||||
if($storyType == 'requirement') $cols['title']['title'] = str_replace($lang->SRCommon, $lang->URCommon, $lang->story->title);
|
||||
if($productType != 'normal')
|
||||
{
|
||||
$cols['branch']['title'] = $lang->product->branchName[$productType];
|
||||
@@ -44,7 +48,7 @@ jsVar('gradeGroup', $gradeGroup);
|
||||
$footToolbar['items'][] = array(
|
||||
'text' => $lang->save,
|
||||
'className' => 'btn secondary batch-btn ajax-btn import-story-btn size-sm',
|
||||
'data-url' => createLink('execution', 'linkStory', "objectID=$object->id")
|
||||
'data-url' => createLink('execution', 'linkStory', "projectID=$object->id&browseType={$browseType}¶m={$param}&orderBy={$orderBy}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}&extra=&storyType=$storyType")
|
||||
);
|
||||
if(!isInModal())
|
||||
{
|
||||
@@ -67,13 +71,13 @@ dtable
|
||||
set::cols($cols),
|
||||
set::data($allStories),
|
||||
set::orderBy($orderBy),
|
||||
set::sortLink(createLink($objectType, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&orderBy={name}_{sortType}")),
|
||||
set::sortLink(createLink($objectType, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&orderBy={name}_{sortType}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}&extra={$extra}&storyType={$storyType}")),
|
||||
set::checkable(true),
|
||||
set::onRenderCell(jsRaw('window.onRenderLinkStoryCell')),
|
||||
set::showToolbarOnChecked(false),
|
||||
set::footToolbar($footToolbar),
|
||||
set::footPager(usePager(array(
|
||||
'linkCreator' => helper::createLink($objectType, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&orderBy=$orderBy&recPerPage={recPerPage}&page={page}&extra=$extra") . "#app={$app->tab}"
|
||||
'linkCreator' => helper::createLink($objectType, 'linkStory', "objectID={$object->id}&browseType={$browseType}¶m={$param}&orderBy=$orderBy&recPerPage={recPerPage}&page={page}&extra=$extra&storyType={$storyType}") . "#app={$app->tab}"
|
||||
)))
|
||||
);
|
||||
|
||||
|
||||
@@ -29,12 +29,13 @@ foreach($allProducts as $productID => $productName)
|
||||
setClass('product-block modal-content center-row justify-start items-center text-left'),
|
||||
checkbox
|
||||
(
|
||||
set::rootClass('w-full p-4 pl-0 clip'),
|
||||
setClass('linked-product cursor-pointer'),
|
||||
set::name("products[{$index}]"),
|
||||
set::text($productName),
|
||||
set::checked(true),
|
||||
set::value($productID),
|
||||
on::click('checkUnlink'),
|
||||
setClass('linked-product')
|
||||
on::click('checkUnlink')
|
||||
),
|
||||
isset($allBranches[$productID][$branchID]) ? picker
|
||||
(
|
||||
@@ -66,6 +67,8 @@ if($execution->grade == 1 || $execution->grade == 2)
|
||||
setClass('product-block modal-content center-row justify-start items-center text-left'),
|
||||
checkbox
|
||||
(
|
||||
set::rootClass('w-full p-4 pl-0 clip'),
|
||||
setClass('cursor-pointer'),
|
||||
set::name("products[{$index}]"),
|
||||
set::text($productName),
|
||||
set::value($productID)
|
||||
|
||||
@@ -48,6 +48,7 @@ body {margin: 0pt}
|
||||
.board-footer.story {bottom: 0;}
|
||||
.board-footer.task {bottom: 0;}
|
||||
.board-footer p{height: 14px; padding:0px 3px; margin-bottom:2px;}
|
||||
.checkbox-primary>label, .radio-primary>label {height:18px;}
|
||||
</style>
|
||||
<?php
|
||||
$i = 0;
|
||||
@@ -111,11 +112,13 @@ $dataType = '';
|
||||
</tr>
|
||||
</table>
|
||||
<?php elseif($dataType == 'bug'):?>
|
||||
<?php unset($lang->bug->statusList['']);?>
|
||||
<div><?php echo $lang->bug->assignTo . ':'; echo empty($content->assignedTo) ? '' : $realnames[$content->assignedTo]->realname;?></div>
|
||||
<div><?php echo $lang->printKanban->taskStatus . ':' . html::checkbox("bug$content->id", $lang->bug->statusList, $content->status);?></div>
|
||||
<?php else:?>
|
||||
<?php unset($lang->task->statusList['']);?>
|
||||
<div><?php echo $lang->task->assign . ':'; echo empty($content->assignedTo) ? '' : $realnames[$content->assignedTo]->realname;?></div>
|
||||
<div><?php echo $lang->printKanban->taskStatus . ':' . html::checkbox("task$content->id", $lang->task->statusList,$content->status);?></div>
|
||||
<div><?php echo $lang->printKanban->taskStatus . ':' . html::checkbox("task$content->id", $lang->task->statusList, $content->status);?></div>
|
||||
<table class='table-1' id='record'>
|
||||
<tr>
|
||||
<td align='center'><?php echo $lang->task->date?></td>
|
||||
|
||||
@@ -17,6 +17,7 @@ jsVar('childrenAB', $lang->story->childrenAB);
|
||||
jsVar('modulePairs', $modulePairs);
|
||||
jsVar('oldShowGrades', $showGrades);
|
||||
jsVar('gradeGroup', $gradeGroup);
|
||||
jsVar('hasProduct', $execution->hasProduct);
|
||||
|
||||
/* Show feature bar. */
|
||||
featureBar
|
||||
@@ -81,12 +82,13 @@ if(!$product)
|
||||
$product->id = 0;
|
||||
}
|
||||
$canModifyProduct = common::canModify('product', $product);
|
||||
$canOpreate['create'] = $canModifyProduct && hasPriv('story', 'create');
|
||||
$canOpreate['batchCreate'] = $canModifyProduct && hasPriv('story', 'batchCreate');
|
||||
$canOpreate['createEpic'] = $canModifyProduct && hasPriv('epic', 'create');
|
||||
$canOpreate['batchCreateEpic'] = $canModifyProduct && hasPriv('epic', 'batchCreate');
|
||||
$canOpreate['createRequirement'] = $canModifyProduct && hasPriv('requirement', 'create');
|
||||
$canOpreate['batchCreateRequirement'] = $canModifyProduct && hasPriv('requirement', 'batchCreate');
|
||||
$canModifyExecution = common::canModify('execution', $execution);
|
||||
$canOpreate['create'] = $canModifyProduct && $canModifyExecution && hasPriv('story', 'create');
|
||||
$canOpreate['batchCreate'] = $canModifyProduct && $canModifyExecution && hasPriv('story', 'batchCreate');
|
||||
$canOpreate['createEpic'] = $canModifyProduct && $canModifyExecution && hasPriv('epic', 'create');
|
||||
$canOpreate['batchCreateEpic'] = $canModifyProduct && $canModifyExecution && hasPriv('epic', 'batchCreate');
|
||||
$canOpreate['createRequirement'] = $canModifyProduct && $canModifyExecution && hasPriv('requirement', 'create');
|
||||
$canOpreate['batchCreateRequirement'] = $canModifyProduct && $canModifyExecution && hasPriv('requirement', 'batchCreate');
|
||||
|
||||
$createLink = createLink('story', 'create', "product={$product->id}&branch=0&moduleID=0&storyID=0&objectID={$execution->id}&bugID=0&planID=0&todoID=0&extra=&storyType={$storyType}") . "#app={$app->tab}";
|
||||
$batchCreateLink = createLink('story', 'batchCreate', "productID={$product->id}&branch=0&moduleID=0&storyID=0&executionID={$execution->id}&plan=0&storyType={$storyType}") . "#app={$app->tab}";
|
||||
@@ -113,9 +115,9 @@ if(in_array($execution->attribute, array('request', 'design')))
|
||||
if($canOpreate['batchCreateRequirement']) $createItem[] = array('text' => $lang->requirement->batchCreate . $lang->URCommon, 'url' => $batchCreateRequirementLink);
|
||||
}
|
||||
|
||||
$canLinkStory = $execution->hasProduct && $canModifyProduct && hasPriv('execution', 'linkStory');
|
||||
$canlinkPlanStory = $execution->hasProduct && $canModifyProduct && hasPriv('execution', 'importPlanStories');
|
||||
$linkStoryUrl = createLink('execution', 'linkStory', "project={$execution->id}");
|
||||
$canLinkStory = ($execution->hasProduct || $app->tab == 'execution') && $canModifyProduct && $canModifyExecution && hasPriv('execution', 'linkStory');
|
||||
$canlinkPlanStory = ($execution->hasProduct || $app->tab == 'execution') && $canModifyProduct && $canModifyExecution && hasPriv('execution', 'importPlanStories') && $storyType == 'story';
|
||||
$linkStoryUrl = createLink('execution', 'linkStory', "project={$execution->id}&browseType=¶m=0&orderBy=id_desc&recPerPage=50&pageID=1&extra=&storyType=$storyType");
|
||||
|
||||
if(commonModel::isTutorialMode())
|
||||
{
|
||||
@@ -124,7 +126,7 @@ if(commonModel::isTutorialMode())
|
||||
$canlinkPlanStory = false;
|
||||
}
|
||||
|
||||
$linkItem = array('text' => $lang->story->linkStory, 'url' => $linkStoryUrl);
|
||||
$linkItem = array('text' => $lang->story->linkStory, 'url' => $linkStoryUrl, 'data-app' => $app->tab);
|
||||
$linkPlanItem = array('text' => $lang->execution->linkStoryByPlan, 'url' => '#linkStoryByPlan', 'data-toggle' => 'modal', 'data-size' => 'sm');
|
||||
|
||||
$createBtnGroup = null;
|
||||
@@ -155,6 +157,24 @@ elseif(count($createItem) == 1)
|
||||
|
||||
$product ? toolbar
|
||||
(
|
||||
common::hasPriv('execution', 'storykanban') && $storyType == 'story' ? btnGroup
|
||||
(
|
||||
btn
|
||||
(
|
||||
setClass('text-primary font-bold shadow-inner bg-canvas'),
|
||||
set::icon('format-list-bulleted'),
|
||||
set::hint($lang->execution->list),
|
||||
set::url(inlink('story', "executionID={$execution->id}&storyType={$storyType}&orderBy={$orderBy}&type=all")),
|
||||
setData('app', $app->tab)
|
||||
),
|
||||
btn
|
||||
(
|
||||
set::icon('kanban'),
|
||||
set::hint($lang->execution->kanban),
|
||||
set::url($this->createLink('execution', 'storykanban', "executionID={$execution->id}")),
|
||||
setData('app', $app->tab)
|
||||
),
|
||||
) : null,
|
||||
hasPriv('story', 'report') ? item(set(array
|
||||
(
|
||||
'text' => $lang->story->report->common,
|
||||
@@ -164,7 +184,7 @@ $product ? toolbar
|
||||
))) : null,
|
||||
hasPriv('story', 'export') ? item(set(array
|
||||
(
|
||||
'text' => $lang->story->export,
|
||||
'text' => $lang->export,
|
||||
'icon' => 'export',
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('story', 'export', "productID={$product->id}&orderBy=$orderBy&executionID=$execution->id&browseType=$type&storyType=$storyType"),
|
||||
@@ -200,7 +220,8 @@ sidebar
|
||||
'modules' => $moduleTree,
|
||||
'activeKey' => $param,
|
||||
'settingLink' => !$execution->hasProduct && !$execution->multiple ? createLink('tree', 'browse', "rootID={$product->id}&viewType=story") : null,
|
||||
'closeLink' => $this->createLink('execution', 'story', "executionID={$execution->id}&storyType={$storyType}&orderBy={$orderBy}&type=byModule¶m=0")
|
||||
'closeLink' => $this->createLink('execution', 'story', "executionID={$execution->id}&storyType={$storyType}&orderBy={$orderBy}&type=byModule¶m=0"),
|
||||
'app' => !$execution->hasProduct && !$execution->multiple ? 'project' : ''
|
||||
)))
|
||||
);
|
||||
|
||||
@@ -292,7 +313,7 @@ $checkObject->execution = $execution->id;
|
||||
$canBatchEdit = common::hasPriv('story', 'batchEdit');
|
||||
$canBatchClose = common::hasPriv('story', 'batchClose') && $storyType != 'requirement';
|
||||
$canBatchChangeStage = common::hasPriv('story', 'batchChangeStage') && $storyType != 'requirement';
|
||||
$canBatchUnlink = common::hasPriv('execution', 'batchUnlinkStory');
|
||||
$canBatchUnlink = ($execution->hasProduct || $app->tab == 'execution') && common::hasPriv('execution', 'batchUnlinkStory');
|
||||
$canBatchToTask = common::hasPriv('story', 'batchToTask', $checkObject) && $storyType != 'requirement';
|
||||
$canBatchAssignTo = common::hasPriv($storyType, 'batchAssignTo');
|
||||
$canBatchAction = $canBeChanged && in_array(true, array($canBatchEdit, $canBatchClose, $canBatchChangeStage, $canBatchUnlink, $canBatchToTask, $canBatchAssignTo));
|
||||
@@ -397,8 +418,9 @@ if($canBatchAction)
|
||||
|
||||
/* DataTable columns. */
|
||||
$config->story->dtable->fieldList['title']['title'] = $lang->story->title;
|
||||
$setting = $this->loadModel('datatable')->getSetting('execution', 'story', false, $storyType);
|
||||
$cols = array();
|
||||
$setting = $this->loadModel('datatable')->getSetting('execution', 'story', false, $storyType);
|
||||
if(!$canModifyExecution) $setting['actions']['actionsMap'] = array();
|
||||
if($storyType == 'requirement') unset($setting['plan'], $setting['stage'], $setting['taskCount'], $setting['bugCount'], $setting['caseCount']);
|
||||
foreach($setting as $col)
|
||||
{
|
||||
@@ -411,24 +433,28 @@ foreach($setting as $col)
|
||||
}
|
||||
|
||||
/* DataTable data. */
|
||||
$data = array();
|
||||
$data = array();
|
||||
$actionMenus = array('submitreview', 'recall', 'recalledchange', 'review', 'dropdown', 'createTask', 'batchCreateTask', 'divider', 'storyEstimate', 'testcase', 'batchCreate', 'unlink');
|
||||
if(empty($execution->hasProduct) && empty($execution->multiple))
|
||||
{
|
||||
$actionMenus = array('submitreview', 'recall', 'recalledchange', 'review', 'dropdown', 'createTask', 'batchCreateTask', 'edit', 'divider', 'storyEstimate', 'testcase', 'batchCreate', 'close');
|
||||
if($storyType == 'requirement') $actionMenus = array('submitreview', 'recall', 'recalledchange', 'review', 'dropdown', 'edit', 'divider', 'batchCreate', 'close');
|
||||
}
|
||||
if(!$canModifyExecution) $actionMenus = array();
|
||||
|
||||
$options = array('storyTasks' => $storyTasks, 'storyBugs' => $storyBugs, 'storyCases' => $storyCases, 'modules' => $modules ?? array(), 'plans' => (isset($plans) ? $plans : array()), 'users' => $users, 'execution' => $execution, 'actionMenus' => $actionMenus, 'branches' => $branchPairs);
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$story->moduleID = $story->module;
|
||||
$story->from = 'execution';
|
||||
$data[] = $this->story->formatStoryForList($story, $options, $storyType, $maxGradeGroup);
|
||||
if(!isset($story->children)) continue;
|
||||
}
|
||||
|
||||
jsVar('cases', $storyCases);
|
||||
jsVar('summary', $summary);
|
||||
jsVar('checkedSummary', $lang->product->checkedAllSummary);
|
||||
jsVar('storyType', $storyType);
|
||||
dtable
|
||||
(
|
||||
setClass('shadow rounded'),
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* The story kanban view file of execution module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
|
||||
* @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Sun Guangming<sunguangming@easycorp.ltd>
|
||||
* @package execution
|
||||
* @link https://www.zentao.net
|
||||
*/
|
||||
|
||||
namespace zin;
|
||||
|
||||
jsVar('cardLang', $lang->kanbancard);
|
||||
jsVar('unlinkLang', $lang->unlink);
|
||||
jsVar('hourUnit', $config->hourUnit);
|
||||
jsVar('executionID', $executionID);
|
||||
jsVar('priv', array(
|
||||
'canViewStory' => common::hasPriv('execution', 'storyView'),
|
||||
'canUnlinkStory' => common::hasPriv('execution', 'unlinkStory'),
|
||||
'canBatchChangeStage' => common::hasPriv('story', 'batchChangeStage')
|
||||
));
|
||||
|
||||
featureBar
|
||||
(
|
||||
li
|
||||
(
|
||||
setClass('nav-item'),
|
||||
a
|
||||
(
|
||||
setClass('active'),
|
||||
set::href(inlink('storykanban', "executionID={$execution->id}")),
|
||||
$lang->execution->kanban,
|
||||
span(setClass('label size-sm rounded-full white'), $total)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$canModifyProduct = common::canModify('product', $product);
|
||||
$canModifyExecution = common::canModify('execution', $execution);
|
||||
$canLinkStory = ($execution->hasProduct || $app->tab == 'execution') && $canModifyProduct && $canModifyExecution && hasPriv('execution', 'linkStory');
|
||||
$canCreate = $canModifyProduct && $canModifyExecution && hasPriv('story', 'create');
|
||||
$canBatchCreate = $canModifyProduct && $canModifyExecution && hasPriv('story', 'batchCreate');
|
||||
$createLink = createLink('story', 'create', "product={$product->id}&branch=0&moduleID=0&storyID=0&objectID={$execution->id}") . "#app={$app->tab}";
|
||||
$batchCreateLink = createLink('story', 'batchCreate', "productID={$product->id}&branch=0&moduleID=0&storyID=0&executionID={$execution->id}") . "#app={$app->tab}";
|
||||
$createItem = array('text' => $lang->story->create, 'url' => $createLink);
|
||||
$batchCreateItem = array('text' => $lang->story->batchCreate, 'url' => $batchCreateLink);
|
||||
$linkStoryUrl = createLink('execution', 'linkStory', "project={$execution->id}");
|
||||
$linkItem = array('text' => $lang->story->linkStory, 'url' => $linkStoryUrl, 'data-app' => $app->tab);
|
||||
$product ? toolbar
|
||||
(
|
||||
common::hasPriv('execution', 'storykanban') ? btnGroup
|
||||
(
|
||||
btn
|
||||
(
|
||||
set::icon('format-list-bulleted'),
|
||||
set::hint($lang->execution->list),
|
||||
set::url(inlink('story', "executionID={$execution->id}")),
|
||||
setData('app', $app->tab)
|
||||
),
|
||||
btn
|
||||
(
|
||||
setClass('text-primary font-bold shadow-inner bg-canvas'),
|
||||
set::icon('kanban'),
|
||||
set::hint($lang->execution->kanban),
|
||||
set::url($this->createLink('execution', 'storykanban', "executionID={$execution->id}")),
|
||||
setData('app', $app->tab)
|
||||
),
|
||||
) : null,
|
||||
hasPriv('story', 'export') ? item(set(array
|
||||
(
|
||||
'text' => $lang->story->export,
|
||||
'icon' => 'export',
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('story', 'export', "productID={$product->id}&orderBy=id_desc"),
|
||||
'data-toggle' => 'modal'
|
||||
))) : null,
|
||||
|
||||
$canCreate && $canBatchCreate ? btngroup
|
||||
(
|
||||
btn
|
||||
(
|
||||
setClass('btn secondary'),
|
||||
set::icon('plus'),
|
||||
set::url($createLink),
|
||||
$lang->story->create
|
||||
),
|
||||
dropdown
|
||||
(
|
||||
btn(setClass('btn secondary dropdown-toggle'),
|
||||
setStyle(array('padding' => '6px', 'border-radius' => '0 2px 2px 0'))),
|
||||
set::items(array_filter(array($createItem, $batchCreateItem))),
|
||||
set::placement('bottom-end')
|
||||
)
|
||||
) : null,
|
||||
|
||||
$canCreate && !$canBatchCreate ? item(set($createItem + array('class' => 'btn primary', 'icon' => 'plus'))) : null,
|
||||
$canBatchCreate && !$canCreate ? item(set($batchCreateItem + array('class' => 'btn primary', 'icon' => 'plus'))) : null,
|
||||
|
||||
$canLinkStory && $canBeChanged ? btngroup
|
||||
(
|
||||
btn(
|
||||
setClass('btn primary'),
|
||||
set::icon('link'),
|
||||
set::url($linkStoryUrl),
|
||||
setData('app', $app->tab),
|
||||
$lang->story->linkStory
|
||||
),
|
||||
) : null,
|
||||
) : null;
|
||||
|
||||
div
|
||||
(
|
||||
set::id('kanban'),
|
||||
zui::kanban
|
||||
(
|
||||
set::key('kanban'),
|
||||
set::data($kanbanData),
|
||||
set::laneNameWidth(0),
|
||||
set::getItem(jsRaw('window.getItem')),
|
||||
set::getLane(jsRaw('window.getLane')),
|
||||
set::canDrop(jsRaw('window.canDrop')),
|
||||
set::onDrop(jsRaw('window.onDrop'))
|
||||
)
|
||||
);
|
||||
@@ -51,6 +51,8 @@ if(common::canModify('execution', $execution))
|
||||
}
|
||||
|
||||
$cols = $this->loadModel('datatable')->getSetting('execution');
|
||||
if($execution->type != 'stage') unset($cols['design']);
|
||||
|
||||
$tableData = initTableData($tasks, $cols, $this->task);
|
||||
$tableData = array_map(
|
||||
function($task)
|
||||
@@ -68,6 +70,7 @@ toolbar
|
||||
(
|
||||
'icon' => 'bar-chart',
|
||||
'class' => 'ghost',
|
||||
'text' => $lang->task->report->common,
|
||||
'url' => createLink('task', 'report', "execution={$execution->id}&browseType={$browseType}")
|
||||
))) : null,
|
||||
hasPriv('task', 'export') ? item(set(array
|
||||
@@ -75,12 +78,14 @@ toolbar
|
||||
'icon' => 'export',
|
||||
'class' => 'ghost export',
|
||||
'url' => createLink('task', 'export', "execution={$execution->id}&orderBy={$orderBy}&type={$browseType}"),
|
||||
'data-toggle' => 'modal'
|
||||
'data-toggle' => 'modal',
|
||||
'text' => $lang->export
|
||||
))) : null,
|
||||
$importItems ? dropdown(
|
||||
btn(
|
||||
setClass('ghost btn square btn-default'),
|
||||
set::icon('import')
|
||||
setClass('ghost btn btn-default'),
|
||||
set::icon('import'),
|
||||
$lang->import
|
||||
),
|
||||
set::items($importItems),
|
||||
set::placement('bottom-end')
|
||||
@@ -108,8 +113,8 @@ sidebar
|
||||
set::modules($moduleTree),
|
||||
set::activeKey($moduleID),
|
||||
set::settingLink(createLink('tree', 'browsetask', "rootID=$execution->id&productID=0")),
|
||||
set::closeLink(createLink('execution', 'task')),
|
||||
set::showDisplay($execution->multiple),
|
||||
set::settingApp($execution->multiple ? 'execution' : 'project'),
|
||||
set::closeLink(createLink('execution', 'task', "executionID={$executionID}")),
|
||||
set::app($app->tab)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -180,10 +180,11 @@ row
|
||||
(
|
||||
setID('importAction'),
|
||||
set::arrow(true),
|
||||
set::caret(false),
|
||||
btn(set::type('link'), set::icon('import'), $lang->import),
|
||||
set::items(array
|
||||
(
|
||||
common::hasPriv('execution', 'importTask') ? array('text' => $lang->execution->importTask, 'url' => createLink('execution', 'importTask', "execution=$execution->id"), 'data-toggle' => 'modal', 'data-size' => 'lg') : null,
|
||||
common::hasPriv('execution', 'importTask') && $execution->multiple ? array('text' => $lang->execution->importTask, 'url' => createLink('execution', 'importTask', "execution=$execution->id")) : null,
|
||||
($features['qa'] && common::hasPriv('execution', 'importBug')) ? array('text' => $lang->execution->importBug, 'url' => createLink('execution', 'importBug', "execution=$execution->id"), 'data-toggle' => 'modal', 'data-size' => 'lg') : null
|
||||
))
|
||||
) : null,
|
||||
@@ -191,6 +192,7 @@ row
|
||||
(
|
||||
setClass('kanbanSetting mr-2'),
|
||||
btn(set::type('link'), icon('ellipsis-v')),
|
||||
set::caret(false),
|
||||
set::items(array
|
||||
(
|
||||
common::hasPriv('execution', 'setKanban') ? array('text' => $lang->execution->setKanban, 'url' => createLink('execution', 'setKanban', "executionID=$execution->id"), 'data-toggle' => 'modal', 'data-size' => 'sm') : null,
|
||||
@@ -232,28 +234,36 @@ div
|
||||
)
|
||||
);
|
||||
|
||||
$linkStoryByPlanTips = $lang->execution->linkNormalStoryByPlanTips;
|
||||
$linkStoryByPlanTips = $execution->multiple ? $linkStoryByPlanTips : str_replace($lang->execution->common, $lang->projectCommon, $linkStoryByPlanTips);
|
||||
|
||||
modal
|
||||
(
|
||||
setID('linkStoryByPlan'),
|
||||
to::header
|
||||
setData('size', '500px'),
|
||||
set::modalProps(array('title' => $lang->execution->linkStoryByPlan)),
|
||||
div
|
||||
(
|
||||
h4($lang->execution->linkStoryByPlan),
|
||||
"({$lang->execution->linkStoryByPlanTips})"
|
||||
setClass('flex-auto'),
|
||||
icon('info-sign', setClass('warning-pale rounded-full mr-1')),
|
||||
$linkStoryByPlanTips
|
||||
),
|
||||
inputGroup
|
||||
form
|
||||
(
|
||||
setClass('mt-1'),
|
||||
picker
|
||||
setClass('text-center', 'py-4'),
|
||||
set::actions(array('submit')),
|
||||
set::submitBtnText($lang->execution->linkStory),
|
||||
formGroup
|
||||
(
|
||||
set::width(200),
|
||||
setID('plan'),
|
||||
set::name('plan'),
|
||||
set::items($allPlans)
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('input-group-btn'),
|
||||
btn(setClass('primary'), setID('toStoryButton'), set::onclick('linkPlanStory()'), $lang->execution->linkStory)
|
||||
set::label($lang->execution->selectStoryPlan),
|
||||
set::required(true),
|
||||
setClass('text-left'),
|
||||
picker
|
||||
(
|
||||
set::name('plan'),
|
||||
set::required(true),
|
||||
set::items($allPlans)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -40,13 +40,13 @@ if(isset($config->testcase->dtable->fieldList['branch'])) $config->testcase->dta
|
||||
if(isset($config->testcase->dtable->fieldList['story'])) $config->testcase->dtable->fieldList['story']['map'] = $stories;
|
||||
if(isset($config->testcase->dtable->fieldList['scene'])) $config->testcase->dtable->fieldList['scene']['map'] = $scenes;
|
||||
$config->testcase->dtable->fieldList['actions']['list']['edit']['url'] = str_replace('%executionID%', (string)$executionID, $config->testcase->dtable->fieldList['actions']['list']['edit']['url']);
|
||||
$config->testcase->dtable->fieldList['actions']['menu'] = array(array('confirmStoryChange'), array('runCase', 'runResult', 'edit', 'createBug', 'create'));
|
||||
$config->testcase->dtable->fieldList['actions']['menu'] = array(array('confirmStoryChange'), array('runCase|ztfRun', 'runResult', 'edit', 'createBug', 'create'));
|
||||
if($config->testcase->needReview) array_unshift($config->testcase->dtable->fieldList['actions']['menu'][1], 'review');
|
||||
$this->config->testcase->dtable->fieldList['title']['link'] = array('module' => 'testcase', 'method' => 'view', 'params' => "caseID={id}");
|
||||
$this->config->testcase->dtable->fieldList['bugs']['link'] = array('module' => 'testcase', 'method' => 'bugs', 'params' => "runID=0&caseID={id}");
|
||||
foreach($config->testcase->dtable->fieldList['actions']['list'] as $method => $action)
|
||||
{
|
||||
if(isset($action['url']) && isset($action['url']['params'])) $config->testcase->dtable->fieldList['actions']['list'][$method]['url']['params'] = str_replace('{caseID}', '{id}', $action['url']['params']);
|
||||
if(isset($action['url']) && isset($action['url']['params'])) $config->testcase->dtable->fieldList['actions']['list'][$method]['url']['params'] = str_replace(array('{caseID}', '{runID}'), array('{id}', '0'), $action['url']['params']);
|
||||
}
|
||||
|
||||
$this->loadModel('testcase');
|
||||
|
||||
@@ -29,6 +29,7 @@ featureBar
|
||||
if(!isset($browseType)) $browseType = 'all';
|
||||
if(!isset($orderBy)) $orderBy = '';
|
||||
|
||||
$canCreateTask = false;
|
||||
$canImportTask = hasPriv('task', 'importTask');
|
||||
$canImportBug = hasPriv('task', 'importBug');
|
||||
if(common::canModify('execution', $execution))
|
||||
@@ -38,6 +39,7 @@ if(common::canModify('execution', $execution))
|
||||
{
|
||||
$importBugItem = array('text' => $lang->execution->importBug, 'url' => $this->createLink('execution', 'importBug', "execution={$execution->id}"), 'className' => 'importBug');
|
||||
}
|
||||
$canCreateTask = hasPriv('task', 'create');
|
||||
}
|
||||
$importItems = !empty($importTaskItem) && empty($importBugItem) ? array($importTaskItem) : array();
|
||||
$importItems = empty($importTaskItem) && !empty($importBugItem) ? array($importBugItem) : $importItems;
|
||||
@@ -48,33 +50,34 @@ toolbar
|
||||
hasPriv('task', 'report') ? item(set(array
|
||||
(
|
||||
'icon' => 'bar-chart',
|
||||
'text' => $lang->task->reportChart,
|
||||
'text' => $lang->task->report->common,
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('task', 'report', "execution={$executionID}&browseType={$browseType}")
|
||||
))) : null,
|
||||
!empty($importItems) ? dropdown(
|
||||
btn(
|
||||
setClass('ghost btn square btn-default'),
|
||||
set::icon('import'),
|
||||
set::text($lang->import)
|
||||
),
|
||||
set::items($importItems),
|
||||
set::placement('bottom-end')
|
||||
) : null,
|
||||
hasPriv('task', 'export') ? item(set(array
|
||||
(
|
||||
'icon' => 'export',
|
||||
'text' => $lang->export,
|
||||
'class' => 'ghost',
|
||||
'url' => createLink('task', 'export', "execution={$executionID}&orderBy={$orderBy}&type=tree"),
|
||||
'data-toggle' => 'modal'
|
||||
'data-toggle' => 'modal',
|
||||
'data-size' => 'sm'
|
||||
))) : null,
|
||||
hasPriv('task', 'create') ? item(set(array
|
||||
!empty($importItems) ? dropdown(
|
||||
btn(
|
||||
setClass('ghost btn btn-default'),
|
||||
set::icon('import'),
|
||||
set::text($lang->import)
|
||||
),
|
||||
set::items($importItems),
|
||||
set::placement('bottom-end')
|
||||
) : null,
|
||||
$canCreateTask ? item(set(array
|
||||
(
|
||||
'icon' => 'plus',
|
||||
'text' => $lang->task->create,
|
||||
'class' => 'primary create-execution-btn',
|
||||
'url' => createLink('task', 'create', "execution={$executionID}" . ($app->tab == 'project' ? '#app=project' : ''))
|
||||
'url' => createLink('task', 'create', "execution={$executionID}") . ($app->tab == 'project' ? '#app=project' : '')
|
||||
))) : null
|
||||
);
|
||||
|
||||
@@ -90,11 +93,11 @@ if(empty($tree))
|
||||
setClass('text-gray'),
|
||||
$lang->task->noTask
|
||||
),
|
||||
common::hasPriv('task', 'create', $checkObject) ? btn
|
||||
$canCreateTask ? btn
|
||||
(
|
||||
set::text($lang->task->create),
|
||||
set::icon('plus'),
|
||||
set::url(createLink('task', 'create', "execution={$executionID}" . (isset($moduleID) ? "&storyID=&moduleID={$moduleID}" : '' . ($app->tab == 'project' ? '#app=project' : '')))),
|
||||
set::url(createLink('task', 'create', "execution={$executionID}" . (isset($moduleID) ? "&storyID=&moduleID={$moduleID}" : '')) . ($app->tab == 'project' ? '#app=project' : '')),
|
||||
setClass('btn primary-pale border-primary ml-2')
|
||||
) : null
|
||||
);
|
||||
|
||||
@@ -18,27 +18,6 @@ $chartURL = createLink('execution', $isKanban ? 'ajaxGetCFD' : 'ajaxGetBurn', "e
|
||||
|
||||
/* Construct suitable actions for the current execution. */
|
||||
$execution->rawID = $execution->id;
|
||||
$operateMenus = array();
|
||||
foreach($config->execution->view->operateList['main'] as $operate)
|
||||
{
|
||||
if(!common::hasPriv('execution', $operate)) continue;
|
||||
if(!$this->execution->isClickable($execution, $operate)) continue;
|
||||
|
||||
$operateMenus[] = $config->execution->actionList[$operate];
|
||||
}
|
||||
|
||||
/* Construct common actions for execution. */
|
||||
$commonActions = array();
|
||||
foreach($config->execution->view->operateList['common'] as $operate)
|
||||
{
|
||||
if(!common::hasPriv('execution', $operate)) continue;
|
||||
|
||||
$settings = $config->execution->actionList[$operate];
|
||||
$settings['text'] = '';
|
||||
if($operate == 'edit') unset($settings['data-toggle']);
|
||||
|
||||
$commonActions[] = $settings;
|
||||
}
|
||||
|
||||
$programDom = null;
|
||||
if($config->systemMode == 'ALM' && isset($execution->projectInfo->grade) && $execution->projectInfo->grade > 1)
|
||||
@@ -110,16 +89,20 @@ if(!empty($execution->projectInfo->hasProduct) || $features['plan'])
|
||||
foreach($product->plans as $planIDList)
|
||||
{
|
||||
$planIDList = explode(',', $planIDList);
|
||||
$planIDList = array_filter($planIDList);
|
||||
foreach($planIDList as $planID)
|
||||
{
|
||||
if(!isset($planGroups[$productID][$planID])) continue;
|
||||
|
||||
$class = '';
|
||||
$class = 'clip';
|
||||
if(count($planIDList) <= 2) $class .= ' flex flex-1 w-0 items-center';
|
||||
if(count($planIDList) > 2) $class .= ' flex-none w-1/3';
|
||||
|
||||
if(count($plans) > 2) $class .= ' mt-2';
|
||||
if(count($plans) % 3 != 0) $class .= ' pl-4';
|
||||
if(count($plans) % 3 != 0) $class .= ' pl-6';
|
||||
$plans[] = div
|
||||
(
|
||||
setClass("flex-none w-1/3 clip {$class}"),
|
||||
setClass($class),
|
||||
icon('calendar mr-2'),
|
||||
a
|
||||
(
|
||||
@@ -161,6 +144,8 @@ div
|
||||
echarts
|
||||
(
|
||||
set::color(array('#2B80FF', '#E3E4E9')),
|
||||
set::width(120),
|
||||
set::height(120),
|
||||
set::series
|
||||
(
|
||||
array
|
||||
@@ -175,7 +160,7 @@ div
|
||||
)
|
||||
)
|
||||
)
|
||||
)->size(120, 120),
|
||||
),
|
||||
div
|
||||
(
|
||||
set::className('pie-chart-title text-center'),
|
||||
@@ -542,14 +527,7 @@ div
|
||||
(
|
||||
h::tr
|
||||
(
|
||||
h::td
|
||||
(
|
||||
div
|
||||
(
|
||||
setClass('flex flex-wrap member-list pt-2'),
|
||||
$membersDom
|
||||
)
|
||||
)
|
||||
h::td(div(setClass('flex flex-wrap member-list pt-2'), $membersDom))
|
||||
)
|
||||
)
|
||||
),
|
||||
@@ -562,14 +540,7 @@ div
|
||||
(
|
||||
h::tr
|
||||
(
|
||||
h::th
|
||||
(
|
||||
div
|
||||
(
|
||||
setClass('flex items-center justify-between'),
|
||||
span($lang->execution->DurationStats)
|
||||
)
|
||||
)
|
||||
h::th(div(setClass('flex items-center justify-between'), span($lang->execution->DurationStats)))
|
||||
)
|
||||
),
|
||||
h::tbody
|
||||
@@ -584,58 +555,26 @@ div
|
||||
div
|
||||
(
|
||||
setClass('w-1/4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->begin
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->begin
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->begin),
|
||||
span(setClass('ml-2'), $execution->begin)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->end
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->end
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->end),
|
||||
span(setClass('ml-2'), $execution->end)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->realBeganAB
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
helper::isZeroDate($execution->realBegan) ? '' : $execution->realBegan
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->realBeganAB),
|
||||
span(setClass('ml-2'), helper::isZeroDate($execution->realBegan) ? '' : $execution->realBegan)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->realEndAB
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
helper::isZeroDate($execution->realEnd) ? '' : $execution->realEnd
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->realEndAB),
|
||||
span(setClass('ml-2'), helper::isZeroDate($execution->realEnd) ? '' : $execution->realEnd)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -649,14 +588,7 @@ div
|
||||
(
|
||||
h::tr
|
||||
(
|
||||
h::th
|
||||
(
|
||||
div
|
||||
(
|
||||
setClass('flex items-center justify-between'),
|
||||
span($lang->execution->lblStats)
|
||||
)
|
||||
)
|
||||
h::th(div(setClass('flex items-center justify-between'), span($lang->execution->lblStats)))
|
||||
)
|
||||
),
|
||||
h::tbody
|
||||
@@ -671,72 +603,32 @@ div
|
||||
div
|
||||
(
|
||||
setClass('w-1/3'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->estimateHours
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->totalEstimate . $lang->execution->workHourUnit
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->estimateHours),
|
||||
span(setClass('ml-2'), $execution->totalEstimate . $lang->execution->workHourUnit)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/3'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->consumedHours
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->totalConsumed . $lang->execution->workHourUnit
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->consumedHours),
|
||||
span(setClass('ml-2'), $execution->totalConsumed . $lang->execution->workHourUnit)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/3'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->leftHours
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->totalLeft . $lang->execution->workHourUnit
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->leftHours),
|
||||
span(setClass('ml-2'), $execution->totalLeft . $lang->execution->workHourUnit)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/3 mt-4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->totalDays
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->days
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->totalDays),
|
||||
span(setClass('ml-2'), $execution->days)
|
||||
),
|
||||
div
|
||||
(
|
||||
setClass('w-1/3 mt-4'),
|
||||
span
|
||||
(
|
||||
setClass('text-gray'),
|
||||
$lang->execution->totalHours
|
||||
),
|
||||
span
|
||||
(
|
||||
setClass('ml-2'),
|
||||
$execution->totalHours . $lang->execution->workHourUnit
|
||||
)
|
||||
span(setClass('text-gray'), $lang->execution->totalHours),
|
||||
span(setClass('ml-2'), $execution->totalHours . $lang->execution->workHourUnit)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -773,17 +665,11 @@ div
|
||||
(
|
||||
h::tr
|
||||
(
|
||||
h::td
|
||||
(
|
||||
div
|
||||
(
|
||||
setClass('flex flex-wrap pt-2'),
|
||||
$docLibDom
|
||||
)
|
||||
)
|
||||
h::td(div(setClass('flex flex-wrap pt-2'), $docLibDom))
|
||||
)
|
||||
)
|
||||
) : null
|
||||
) : null,
|
||||
html($this->printExtendFields($execution, 'html', 'position=info', false))
|
||||
)
|
||||
),
|
||||
div
|
||||
@@ -793,11 +679,7 @@ div
|
||||
(
|
||||
to::heading
|
||||
(
|
||||
div
|
||||
(
|
||||
set('class', 'panel-title'),
|
||||
$lang->execution->latestDynamic
|
||||
)
|
||||
div(set('class', 'panel-title'), $lang->execution->latestDynamic)
|
||||
),
|
||||
to::headingActions
|
||||
(
|
||||
@@ -812,6 +694,7 @@ div
|
||||
set::shadow(false),
|
||||
dynamic()
|
||||
),
|
||||
html($this->printExtendFields($execution, 'html', 'position=basic', false)),
|
||||
div
|
||||
(
|
||||
setClass('mt-4'),
|
||||
@@ -824,14 +707,15 @@ div
|
||||
)
|
||||
);
|
||||
|
||||
$actions = $this->loadModel('common')->buildOperateMenu($execution);
|
||||
div
|
||||
(
|
||||
setClass('center w-2/3'),
|
||||
setClass('w-2/3 center fixed actions-menu'),
|
||||
floatToolbar
|
||||
(
|
||||
isAjaxRequest('modal') ? null : to::prefix(backBtn(set::icon('back'), $lang->goback)),
|
||||
set::main($operateMenus),
|
||||
set::suffix($commonActions),
|
||||
set::main($actions['mainActions']),
|
||||
set::suffix($actions['suffixActions']),
|
||||
set::object($execution)
|
||||
)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user