* @package flow * @link https://www.zentao.net */ namespace zin; include 'header.html.php'; $activeTab = $flow->module; if($currentType) { if($currentMode == 'bysearch') $activeTab = 'common'; if(isset($linkedDatas[$currentType])) $activeTab = $currentType; } $canLink = $this->flow->isClickable($flow->module, 'link', $data); $sessionName = $flow->module . 'List'; $browseLink = $this->session->$sessionName ? $this->session->$sessionName : $this->createLink($flow->module, 'browse'); $loadLink = $this->createLink($flow->module, 'link', "dataID=$data->id&linkType=LINKTYPE&mode=MODE"); jsVar('moduleName', $flow->module); jsVar('linkType', $currentType); jsVar('viewMode', $currentMode); jsVar('loadLink', $loadLink); detailHeader ( to::prefix(backBtn ( setClass('primary'), set::icon('back'), setData('app', $app->tab), $lang->goback ), entityLabel(set(array('entityID' => $data->id, 'text' => zget($dataPairs, $data->id), 'textClass' => array('font-bold'))))) ); $obj = $this; $showFields = function($fields, $childFields, $relations, $data, $position = 'info') use ($childDatas, $obj) { global $lang; $html = ''; $children = array(); foreach($fields as $field) { if(empty($field->show)) continue; if(isset($childFields[$field->field])) { $children[$field->field] = $field->name; continue; } if($field->position != $position) continue; if($field->control == 'file') { $filesName = "{$field->field}files"; if(!empty($data->{$filesName})) $html .= '

' . $field->name . $lang->hyphen . '' . $this->flow->getFieldValue($field, $data) . '

'; } else { $attr = ''; $relation = zget($relations, $field->field, ''); if($relation && strpos(",$relation->actions,", ',many2one,') === false && strpos(",$relation->actions,", ',many2many,') === false) { $prevDataID = isset($data->{$field->field}) ? $data->{$field->field} : 0; if($prevDataID) $attr = "class='prevField' data-prev='{$relation->prev}' data-next='{$relation->next}' data-action='view' data-dataid='$prevDataID'"; } if($field->control == 'textarea') $attr .= " class='article'"; $html .= "

{$field->name}"; if($field->control == 'textarea') $html .= '
'; $fieldValue = ''; if(!empty($data->{$field->field})) { if(is_array($data->{$field->field})) { foreach($data->{$field->field} as $value) $fieldValue .= $obj->flow->processFieldValue($field, $relation, $value) . ' '; } else { $fieldValue = $obj->flow->processFieldValue($field, $relation, $data->{$field->field}); } } else { if(isset($data->{$field->field}) && $data->{$field->field} === '0') $fieldValue = '0'; } if($fieldValue !== '') $html .= $field->control == 'textarea' ? $fieldValue : ' ' . $lang->hyphen . ' ' . $fieldValue; $html .= '

'; } } foreach($children as $child => $childName) { if(empty($childDatas[$child])) continue; $html .= "
{$childName}
"; foreach($childFields[$child] as $childField) { if(!$childField->show) continue; $childWidth = ($childField->width && $childField->width != 'auto' ? $childField->width . 'px' : 'auto'); $html .= ""; } $html .= ""; foreach($childDatas[$child] as $childData) { $html .= ""; foreach($childFields[$child] as $childField) { if(!$childField->show) continue; if(strpos(',date,datetime,', ",$childField->control,") !== false) { $childValue = formatTime($childData->{$childField->field}); } else { if(is_array($childData->{$childField->field})) { $childValues = array(); foreach($childData->{$childField->field} as $value) { if(!empty($value)) $childValues[] = zget($childField->options, $value); } $childValue = implode(',', $childValues); } else { $childValue = zget($childField->options, $childData->{$childField->field}); } } $html .= ""; } $html .= ""; } $html .= "
{$childField->name}
{$childValue}
"; } return $html; }; $showSide = function() use ($processBlocks, $childFields, $relations, $obj, $data, $flow) { $buildBlock = function($blockFields) use ($obj, $childFields, $relations, $data) { $html = ""; foreach($blockFields as $field) { if(!$field->show) continue; if(isset($childFields[$field->field])) continue; /* Display data of the prev flow. */ $attr = ''; $link = ''; $relation = zget($relations, $field->field, ''); if($relation && strpos(",$relation->actions,", ',many2one,') === false) { $prevDataID = isset($data->{$field->field}) ? $data->{$field->field} : 0; $attr = "class='prevTR' data-prev='{$relation->prev}' data-next='{$relation->next}' data-action='view' data-dataid='$prevDataID'"; if(hasPriv($relation->prev, 'view')) $link = createLink($relation->prev, 'view', "dataID=$prevDataID"); } $html .= ""; } $html .= "
{$field->name}"; if($field->control == 'file') { $filesName = "{$field->field}files"; $html .= $obj->fetch('file', 'printFiles', array('files' => $data->{$filesName}, 'fieldset' => 'false')); } elseif(is_array($data->{$field->field})) { foreach($data->{$field->field} as $value) $html .= zget($field->options, $value) . ' '; } else { if(strpos(',date,datetime,', ",$field->control,") !== false) { $html .= formatTime($data->{$field->field}); } else { $fieldValue = zget($field->options, $data->{$field->field}); $html .= $link ? html::a($link, $fieldValue) : $fieldValue; } } $html .= "
"; return $html; }; $html = ''; foreach($processBlocks as $blockKey => $block) { $html .= "
"; if(empty($block->tabs)) { if($block->name) $html .= "
{$block->name}
"; } else { $html .= "
"; $html .= "
"; } if(!empty($block->tabs)) { $html .= "
"; $index = 1; foreach($block->tabs as $tabKey => $tab) { $class = $index == 1 ? 'active' : ''; $html .= "
"; $html .= $buildBlock($tab->fields); $html .= "
"; $index ++; } $html .= "
"; } elseif(!empty($block->fields)) { $html .= $buildBlock($block->fields); } $html .= "
"; } global $lang; $relatedObjectHTML = wg(relatedObjectList(set::objectID($data->id), set::objectType("workflow_{$flow->module}"), set::browseType('byObject')))->renderInner(); $html .= "
{$lang->custom->relateObject}
$relatedObjectHTML
"; return $html; }; $canUnlink = $this->flow->isClickable($flow->module, 'unlink', $data); $buildLinked = function($linkType, $dataList) use($canUnlink, $obj, $flow, $data, $currentType, $uiID, $activeTab) { global $config, $lang; $html = ''; if(in_array($linkType, $config->flow->linkPairs)) { list($linkedApp, $linkedModule) = $obj->flow->extractAppAndModule($linkType); $html .= $obj->fetch($linkedModule, 'linked', "module=$flow->module&dataID=$data->id&linkType=$currentType", $linkedApp); return $html; } $linkedFields = $obj->workflowaction->getFields($linkType, 'browse', true, $dataList, $uiID); $active = $activeTab == $linkType ? 'active' : ''; $batchActions = ''; $canBatchAction = $config->flow->showBatchActionsInLinkedPage; if($canBatchAction) { $batchActions = $obj->flow->buildBatchActions($linkType); $canBatchAction = !empty($batchActions); } if($currentMode != 'browse') return $html; $html .= "
"; $html .= ""; $index = 1; foreach($linkedFields as $field) { if(!$field->show) continue; if(!$canUnlink && $field->field == 'actions') continue; $width = ($field->width && $field->width != 'auto' ? $field->width . 'px' : 'auto'); $fieldName = $field->name; if($index == 1 && ($canUnlink or $canBatchAction)) $fieldName = "
"; $html .= ""; $index++; } $html .= ""; foreach($dataList as $linkedData) { $html .= ""; $index = 1; foreach($linkedFields as $field) { if(!$field->show or $field->field == 'actions') continue; $output = ''; if(is_array($linkedData->{$field->field})) { foreach($linkedData->{$field->field} as $value) $output .= zget($field->options, $value) . ' '; } else { if($field->field == 'id') { $output = $linkedData->id; if(hasPriv($linkType, 'view')) { $action = $obj->workflowaction->getByModuleAndAction($linkType, 'view'); $attr = $action->open == 'modal' ? "data-toggle='modal'" : ''; $output = baseHTML::a(helper::createLink($linkType, 'view', "dataID={$linkedData->id}"), $linkedData->id, $attr); } } else { $output = zget($field->options, $linkedData->{$field->field}); } } $html .= ""; } $html .= ""; } $html .= "
{$fieldName}
"; $fieldValue = $output; if($index == 1 && ($canUnlink or $canBatchAction)) { $fieldValue = "
"; if($field->field == 'id')$fieldValue .= $output; } $index++; } if($canUnlink) { $html .= "
"; $confirm = sprintf($lang->flow->unlinkConfirm, zget($linkPairs, $linkType)); $html .= baseHTML::a(createLink($flow->module, 'unlink', "dataID=$data->id&linkType=$linkType&linkedID=$linkedData->id"), $lang->flow->unlink, "class='unlink' data-confirm='$confirm' onclick='unlinkData(this)'"); $html .= "
"; return $html; }; $buildOperateMenu = function() use($flow, $data, $obj, $browseLink, $groupID) { if(zget($data, 'deleted', '0') == '1' || !$flow) return ''; global $lang, $config, $app; $obj->loadModel('workflowaction'); $menu = "
"; $menu .= "{$lang->goback}"; $menu .= "
"; $relations = $obj->dao->select('next, actions')->from(TABLE_WORKFLOWRELATION)->where('prev')->eq($flow->module)->fetchPairs(); $actions = $obj->workflowaction->getList($flow->module, 'status_desc,order_asc', $groupID); foreach($actions as $action) $menu .= $obj->flow->buildActionMenu($flow->module, $action, $data, 'view', $relations); if(!empty($config->openedApproval) && $flow->approval == 'enabled' && hasPriv('approval', 'progress') && !empty($data->approval)) { $menu .= "
"; $menu .= html::a(helper::createLink('approval', 'progress', "approvalID={$data->approval}"), $lang->flow->approvalProgress, '', "class='btn ghost' data-toggle='modal'"); } $menu .= '
'; $menu = str_replace(array('module), set::title($flow->name . $lang->flow->detail), set::active($activeTab == $flow->module), setClass('relative'), $canLink ? div ( setClass('tab-actions'), btn(setClass('primary'), setData('toggle', 'modal'), set::url('#linkTypeBox'), set::text($lang->workflowaction->default->actions['link'])) ) : null, row ( cell ( setClass('mainbar w-3/4 mr-3'), html("
" . $showFields($fields, $childFields, $relations, $data) . '
'), history(set::objectType($flow->module), set::objectID($data->id)), html($buildOperateMenu()) ), cell ( setClass('sidebar w-1/4'), html($showSide()) ) ) ); foreach($linkedDatas as $linkType => $datas) { $tabPanes[] = tabPane ( set::key($linkType), set::title(zget($linkPairs, $linkType, '')), set::active($activeTab == $linkType), setClass('relative'), $canLink ? div ( setClass('tab-actions'), btn(setClass('primary'), setData('toggle', 'modal'), set::url('#linkTypeBox'), set::text($lang->workflowaction->default->actions['link'])) ) : null, html($buildLinked($linkType, $datas)) ); } if($canLink) { $tabPanes[] = tabPane ( set::key('common'), set::active($activeTab == 'common'), div ( setClass('tab-actions'), btn(setClass('primary'), setData('toggle', 'modal'), set::url('#linkTypeBox'), set::text($lang->workflowaction->default->actions['link'])) ) ); modal ( setID('linkTypeBox'), set::closeBtn(true), set::title($lang->workflowaction->default->actions['link']), on::change('[name=linkType]', 'linkData'), formGroup ( set::label($lang->flow->selectLinkType), picker(set::name('linkType'), set::items(array('' => '') + $linkPairs)) ) ); } $buttons = array(); $linkCreator = createLink($app->rawModule, $app->rawMethod, 'dataID={id}'); if(!empty($preAndNext->pre)) { $buttons[] = btn ( setClass('detail-prev-btn absolute top-0 left-0 inverse rounded-full w-12 h-12 center bg-opacity-40 backdrop-blur ring-0'), set::icon('angle-left icon-2x text-canvas'), setData('app', $app->tab), set('hint', "#{$preAndNext->pre->id}"), set('url', str_replace('{id}', "{$preAndNext->pre->id}", $linkCreator)) ); } if(!empty($preAndNext->next)) { $buttons[] = btn ( setClass('detail-next-btn absolute top-0 right-0 inverse rounded-full w-12 h-12 center bg-opacity-40 backdrop-blur ring-0'), set::icon('angle-right icon-2x text-canvas'), setData('app', $app->tab), set('hint', "#{$preAndNext->next->id}"), set('url', str_replace('{id}', "{$preAndNext->next->id}", $linkCreator)) ); } div ( on::init()->call('loadAllPrevData'), tabs($tabPanes), !empty($buttons) ? div ( setClass('detail-prev-next fixed top-0 left-0 bottom-0 right-0 z-10 pointer-events-none'), div ( setClass('container relative pointer-events-auto'), setStyle(array('top' => '50%', 'margin' => '-24px auto auto')), $buttons ) ) : null );