* @package project * @link https://www.zentao.net */ namespace zin; jsVar('browseType', $browseType); jsVar('param', $param); jsVar('recTotal', $pager->recTotal); jsVar('recPerPage', $pager->recPerPage); jsVar('pageID', $pager->pageID); /* zin: Define the feature bar on main menu. */ unset($programs[0]); featureBar ( helper::hasFeature('program') ? to::before ( div ( picker ( set::name('programID'), set::value($programID), set::items($programs), set::width('200px'), set::placeholder($lang->project->selectProgram), on::change('changeProgram') ) ) ) : null, set::current($browseType), set::linkParams("programID={$programID}&status={key}¶m=&orderBy={$orderBy}&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"), checkbox ( set::rootClass('mx-2'), set::name('involved'), set::text($lang->project->mine), set::checked($this->cookie->involved ? 'checked' : '') ), li(searchToggle(set::module('project'), set::open($browseType == 'bysearch'))) ); /* zin: Define the toolbar on main menu. */ toolbar ( item(set(array ( 'type' => 'btnGroup', 'items' => array(array ( 'icon' => 'list', 'class' => 'switchButton btn-icon', 'data-type' => 'bylist', 'hint' => $lang->project->bylist ), array ( 'icon' => 'cards-view', 'class' => 'btn-icon switchButton text-primary', 'data-type' => 'bycard', 'hint' => $lang->project->bycard )) ))), hasPriv('project', 'export') ? item(set(array ( 'icon' => 'export', 'text' => $lang->project->export, 'class' => 'ghost export', 'url' => createLink('project', 'export', "status={$browseType}&orderBy={$orderBy}"), 'data-toggle' => 'modal' ))) : null, hasPriv('project', 'create') ? item(set(array ( 'icon' => 'plus', 'text' => $lang->project->create, 'class' => 'primary create-project-btn', 'url' => createLink('project', 'createGuide', "programID={$programID}"), 'data-toggle' => 'modal', 'data-position' => 'center' ))) : null ); $projectCards = null; if(!empty($projectStats)) { foreach($projectStats as $project) { $status = isset($project->delay) ? 'delay' : $project->status; $statusLabel = $config->project->statusLabelList[$status]; $project->end = $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end; $project->date = str_replace('-', '.', $project->begin) . ' - ' . str_replace('-', '.', $project->end); $count = 0; $memberAvatars = null; $lastMember = end($project->teamMembers); if(!empty($project->teamMembers)) { foreach($project->teamMembers as $key => $member) { if(!isset($users[$member])) { $project->teamCount --; unset($project->teamMembers[$key]); continue; } if($count > 2) continue; $memberAvatars[] = div ( setClass('avatar circle size-sm'), set::title($users[$member]), avatar ( set::size('sm'), set::text($users[$member]), set::src(zget($usersAvatar, $member, '')) ) ); $count ++; } } $actionItems = array(); $actionParams = "projectID={$project->id}"; $actionList = array('edit', 'start', 'suspend', 'close', 'activate'); foreach($actionList as $action) { if(!common::hasPriv('project', $action)) continue; $actionItem = $config->project->actionList[$action]; if($this->project->isClickable($project, $action)) { $actionItem['url'] = createLink('project', $action, $actionParams); $actionItem['className'] = 'text-primary'; } else { unset($actionItem['url']); $actionItem['disabled'] = true; } $actionItems[] = $actionItem; } $projectCards[] = div ( setClass('col'), set('data-id', $project->id), div ( setClass('panel'), div ( setClass('panel-heading'), span ( setClass('label project-type-label'), setClass(in_array($project->model, array('waterfall', 'waterfallplus')) ? 'warning-pale ring-warning' : 'secondary-pale ring-secondary'), icon($project->model == 'scrum' ? 'sprint' : $project->model) ), a ( setClass('project-name'), set::href(createLink('project', 'index', "projectID={$project->id}")), set::title($project->name), h::strong($project->name) ), span ( setClass("project-status label rounded-full {$statusLabel}"), $status != 'delay' ? $lang->project->statusList[$status] : sprintf($lang->project->delayInfo, $project->delay) ) ), div ( setClass('panel-body'), div ( setClass('project-infos'), span ( set::title($project->budget), setClass('label gray-100'), $project->budget ), span ( set::title($project->date), setClass('label gray-100 mr-2'), setStyle('color', $status == 'delay' ? 'var(--color-danger-500)' : 'inherit'), $project->date ) ), div ( setClass('project-detail pl-8 pt-2'), div ( setClass('row'), div ( setClass($app->getClientLang() == 'en' ? 'w-1/3' : 'w-1/4'), div ( span ( setClass('statistics-title'), $lang->projectCommon . $lang->project->progress ) ), div ( setClass('pl-4'), set('data-zui', 'ProgressCircle'), set('data-percent', $project->progress), set('data-size', 24), set('data-circle-color', 'var(--color-success-500)') ) ), div ( setClass('w-1/3 text-center'), span ( setClass('statistics-title'), $lang->project->leftTasks ), span ( setClass('leftTasks'), set::title($project->leftTasks), $project->leftTasks ) ), div ( setClass('w-1/3 text-center'), span ( setClass('statistics-title'), $lang->project->leftHours ), span ( setClass('totalLeft'), set::title(empty($project->left) ? '— ' : $project->left . 'h'), empty($project->left) ? '— ' : $project->left . 'h' ) ) ) ), div ( setClass('project-footer pt-2'), div ( setClass('project-team'), div ( setClass('project-members avatar-group gap-4'), $memberAvatars, $project->teamCount > 4 ? span ( '…' ) : null, $project->teamCount > 3 ? div ( setClass('avatar size-sm circle'), set::title($users[$lastMember]), avatar ( set::size('sm'), set::text($users[$lastMember]), set::src(zget($usersAvatar, $lastMember, '')) ) ) : null, a ( setClass('project-members-total pl-2 mt-1'), set::href(createLink('project', 'team', "projectID={$project->id}")), sprintf($lang->project->teamSumCount, $project->teamCount) ) ) ), div ( setClass('project-actions'), $actionItems ? dropdown ( set::caret(false), btn ( setClass('ghost btn square btn-default'), set::icon('ellipsis-v') ), set::placement('left-end'), set::menu(array('class' => 'flex p-2 project-menu-actions')), set::items($actionItems) ) : null ) ) ) ) ); } } div ( setID('cards'), setClass('row cell'), empty($projectStats) ? div ( setClass('table-empty-tip w-full'), span ( setClass('text-gray'), $lang->project->empty ), hasPriv('project', 'create') ? btn(set(array ( 'icon' => 'plus', 'text' => $lang->project->create, 'class' => 'ml-2', 'url' => createLink('project', 'createGuide'), 'data-toggle' => 'modal', 'data-position' => 'center' ))) : null ) : $projectCards, !empty($projectStats) ? div ( setID('cardsFooter'), pager(set(usePager())) ) : null ); /* ====== Render page ====== */ render();