* code for task #2563.
This commit is contained in:
@@ -509,11 +509,11 @@ class commonModel extends model
|
||||
if(isset($menuItem->link['method'])) $method = $menuItem->link['method'];
|
||||
}
|
||||
if($float != 'right' and $module == $currentModule and ($method == $currentMethod or strpos(",$alias,", ",$currentMethod,") !== false)) $active = 'active';
|
||||
echo "<li class='$float $active'>" . html::a($link, $menuItem->text, $target, "data-id='$menuItem->name'") . "</li>\n";
|
||||
echo "<li class='$float $active' data-id='$menuItem->name'>" . html::a($link, $menuItem->text, $target) . "</li>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<li>$menuItem->text</li>\n";
|
||||
echo "<li data-id='$menuItem->name'>$menuItem->text</li>\n";
|
||||
}
|
||||
}
|
||||
echo "</ul>\n";
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<script type='text/javascript'>
|
||||
$(function()
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td class='linkbox'>
|
||||
<?php
|
||||
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
|
||||
$tasksLink = $this->createLink('storybtn-task-create', 'tasks', "storyID=$story->id&projectID=$project->id");
|
||||
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
|
||||
?>
|
||||
</td>
|
||||
@@ -97,7 +97,7 @@
|
||||
$param = "projectID={$project->id}&story={$story->id}&moduleID={$story->module}";
|
||||
|
||||
$lang->task->create = $lang->project->wbs;
|
||||
common::printIcon('task', 'create', $param, '', 'list', 'list-ul', '', '.btn-task-create');
|
||||
common::printIcon('task', 'create', $param, '', 'list', 'list-ul', '', 'btn-task-create');
|
||||
|
||||
$lang->task->batchCreate = $lang->project->batchWBS;
|
||||
common::printIcon('task', 'batchCreate', "projectID={$project->id}&story={$story->id}", '', 'list', 'stack');
|
||||
|
||||
@@ -27,7 +27,7 @@ class tutorial extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function index($task = '')
|
||||
public function index($referer = '', $task = '')
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
@@ -48,6 +48,7 @@ class tutorial extends control
|
||||
$this->view->title = $this->lang->tutorial->common;
|
||||
$this->view->current = $task;
|
||||
$this->view->setting = $setting;
|
||||
$this->view->referer = base64_decode($referer);
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,33 @@
|
||||
#task {border: none}
|
||||
#task > .panel-heading {padding: 10px; background: #114f8e; color: #fff; font-size: 15px; transition: background .4s;}
|
||||
#task > .panel-heading > .pull-right {margin-top: 3px; opacity: 0; transition: opacity .4s, transform .4s; transform: scale(2.5, 2)}
|
||||
#task > .panel-body {border: 1px solid #ddd; border-top: none; padding: 10px}
|
||||
#task > .panel-body > ul, #task > .panel-body > p {margin: 0; line-height: 20px;}
|
||||
#task > .panel-body {border: 1px solid #ddd; border-top: none; padding: 0}
|
||||
#task .panel-body > .btn {padding:5px 7px;}
|
||||
#task .task-desc > ul, #task .task-desc > p {line-height: 20px;}
|
||||
#task .task-desc {padding: 10px}
|
||||
#task .task-desc > ul {list-style: none; padding-left: 0; margin: 0;}
|
||||
#task .task-desc > ul > li {position: relative; padding: 2px 0; overflow: hidden; padding-left: 26px; transition: background .5s}
|
||||
#task .task-desc > ul > li[data-target].finish {color: #999; text-decoration: line-through;}
|
||||
#task .task-desc > ul > li[data-target].finish .task-nav {opacity: .6; text-decoration: line-through;}
|
||||
#task .task-desc > ul > li:before {font-family: ZenIcon; font-size: 14px; font-style: normal; font-weight: 400; font-variant: normal; line-height: 1; text-transform: none; speak: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; content: '\e6ec'; display: block; width: 26px; height: 20px; line-height: 20px; text-align: center; opacity: .6; color: #808080; position: absolute; top: 2px; left: 0}
|
||||
#task .task-desc > ul > li[data-target]:after {content: ' '; display: block; position: absolute; left: 0; top: -100%; width: 100%; height: 100%; border: 2px solid #F1A325; transition: top .5s}
|
||||
#task .task-desc > ul > li[data-target]:before {content: '\e6e8'; color: #333}
|
||||
#task .task-desc > ul > li[data-target].finish:after {top: 100%;}
|
||||
#task .task-desc > ul > li[data-target].finish:before {content: '\e653'; color: #38B03F}
|
||||
#task .task-desc > ul > li[data-target].active {background: #FFF0D5}
|
||||
#task .task-desc > ul > li[data-target].active:after {top: 0%}
|
||||
#task .task-desc > ul > li[data-target].active:before {color: #EA644A; content: '\f192'}
|
||||
#openTaskPage {display: block; overflow: hidden; position: relative; height: 36px; background: #f5f5f5}
|
||||
#openTaskPage > div {padding: 8px 10px; line-height: 20px; transition: top .4s cubic-bezier(.175,.885,.32,1); position: absolute; left: 0; top: 0; right: 0}
|
||||
#openTaskPage > div > .icon {display: inline-block; width: 30px; text-align: center}
|
||||
#openTaskPage:hover {background: #EBF2F9}
|
||||
#openTaskPage > .normal {top: 0;}
|
||||
#openTaskPage.open {color: #38B03F; background: #DDF4DF}
|
||||
#openTaskPage.open:hover {color: #1a4f85; background: #EBF2F9}
|
||||
#openTaskPage > .opened, #openTaskPage > .reload, #openTaskPage.open > .reload {top: 36px;}
|
||||
#openTaskPage.open > .normal, #openTaskPage.open:hover > .opened {top: -36px;}
|
||||
#openTaskPage.open > .opened, #openTaskPage.open:hover > .reload {top: 0;}
|
||||
|
||||
#task.finish > .panel-heading {background: #38B03F}
|
||||
#task.finish > .panel-heading .task-name {text-decoration: line-through;}
|
||||
#task.finish.finish > .panel-heading > .pull-right {opacity: 1; transform: scale(1)}
|
||||
@@ -29,11 +54,13 @@
|
||||
#tasks > li.finish > a > .task-name {text-decoration: line-through;}
|
||||
#tasks > li.active > a, #tasks > li.active.finish > a {box-shadow: inset 2px 0 0 #114f8e; border-color: #ddd; border-left-color: #114f8e; color: #114f8e; background: #EBF2F9}
|
||||
#tasks > li.finish > a:hover, #tasks > li.active > a:hover {background-color: #f1f1f1}
|
||||
#finish {background: #38B03F; color: #fff; text-align: center; overflow: hidden; height: 220px; margin-top: -220px; transform: scale(.5); transition: margin-top .4s, transform .4s, opacity .4s; opacity: 0; transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1)}
|
||||
#finish.show {margin-top: 0; transform: scale(1); opacity: 1}
|
||||
#finish > h3 {margin-bottom: 20px}
|
||||
#finish .start-icon > .icon-spin {-moz-animation: spin 10s infinite linear;-o-animation: spin 10s infinite linear;-webkit-animation: spin 10s infinite linear;animation: spin 10s infinite linear;}
|
||||
#finish .start-icon {width: 60px; height: 60px; text-align: center; margin: 10px auto; position: relative}
|
||||
#finish .start-icon > .icon-front {color: #38B03F; width: 60px; height: 60px; line-height: 60px; position: absolute; left: 0; top: 0; font-size: 28px;}
|
||||
#finish .start-icon > .icon-back {font-size: 56px; color: #fff; line-height: 60px;}
|
||||
#finish .btn-success {border-color: #DDF4DF}
|
||||
|
||||
#taskModalBack {position: absolute; top: 0; left: 0; bottom: 0; right: 0; background: #fff; opacity: .6; transition: opacity .4s; opacity: 0; display: none}
|
||||
#taskModal {width: 500px; position: absolute; background: #38B03F; color: #fff; text-align: center; overflow: hidden; transform: scale(.5) translate(0, 200px) rotateX(120deg); transition: transform .4s, opacity .4s; opacity: 0; transition-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1); top: 0; padding: 30px; left: 50%; margin-left: -250px; top: 20%; box-shadow: 0 3px 9px rgba(0,0,0,.5); display: none}
|
||||
#taskModal.in {transform: scale(1) translate(0) rotateX(0); opacity: 1}
|
||||
#taskModal h3 {margin-bottom: 20px}
|
||||
#taskModal .start-icon > .icon-spin {-moz-animation: spin 10s infinite linear;-o-animation: spin 10s infinite linear;-webkit-animation: spin 10s infinite linear;animation: spin 10s infinite linear;}
|
||||
#taskModal .start-icon {width: 60px; height: 60px; text-align: center; margin: 10px auto; position: relative}
|
||||
#taskModal .start-icon > .icon-front {color: #38B03F; width: 60px; height: 60px; line-height: 60px; position: absolute; left: 0; top: 0; font-size: 28px;}
|
||||
#taskModal .start-icon > .icon-back {font-size: 56px; color: #fff; line-height: 60px;}
|
||||
#taskModal .btn-success {border-color: #DDF4DF}
|
||||
|
||||
@@ -11,45 +11,48 @@
|
||||
*/
|
||||
|
||||
$lang->tutorial = new stdclass();
|
||||
$lang->tutorial->common = '新手教程';
|
||||
$lang->tutorial->desc = '通过完成一系列任务,快速了解禅道的基本使用方法。这可能会花费您10分钟,你可以随时退出任务。';
|
||||
$lang->tutorial->start = '立即开始';
|
||||
$lang->tutorial->exit = '退出任务';
|
||||
$lang->tutorial->congratulation = '恭喜,你已完成了所有任务!';
|
||||
$lang->tutorial->restart = '重新开始';
|
||||
$lang->tutorial->currentTask = '当前任务';
|
||||
$lang->tutorial->allTasks = '所有任务';
|
||||
$lang->tutorial->previous = '上一个';
|
||||
$lang->tutorial->nextTask = '下一个任务';
|
||||
$lang->tutorial->common = '新手教程';
|
||||
$lang->tutorial->desc = '通过完成一系列任务,快速了解禅道的基本使用方法。这可能会花费您10分钟,你可以随时退出任务。';
|
||||
$lang->tutorial->start = '立即开始';
|
||||
$lang->tutorial->exit = '退出任务';
|
||||
$lang->tutorial->congratulation = '恭喜,你已完成了所有任务!';
|
||||
$lang->tutorial->restart = '重新开始';
|
||||
$lang->tutorial->currentTask = '当前任务';
|
||||
$lang->tutorial->allTasks = '所有任务';
|
||||
$lang->tutorial->previous = '上一个';
|
||||
$lang->tutorial->nextTask = '下一个任务';
|
||||
$lang->tutorial->openTargetPage = '打开 <strong class="task-page-name">目标</strong> 页面';
|
||||
$lang->tutorial->atTargetPage = '已在 <strong class="task-page-name">目标</strong> 页面';
|
||||
$lang->tutorial->reloadTargetPage = '重新载入';
|
||||
$lang->tutorial->target = '目标';
|
||||
$lang->tutorial->tagetPageTip = '按此指示打开【%s】页面';
|
||||
|
||||
$lang->tutorial->tasks = array();
|
||||
|
||||
$lang->tutorial->tasks['createAccount'] = array('title' => '创建账号');
|
||||
$lang->tutorial->tasks['createAccount']['nav'] = array('module' => 'company', 'method' => 'create', 'menu' => 'addUser', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createAccount']['desc'] = "<p>在系统创建一个新的用户账号:</p><ul><li>打开 <span class='task-nav'>组织 <i class='icon icon-angle-right'></i> 用户 <i class='icon icon-angle-right'></i> 添加用户</span> 页面;</li><li>在添加用户表单中填写新用户信息;</li><li>保存用户信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createAccount']['nav'] = array('module' => 'user', 'method' => 'create', 'menuModule' => 'company', 'menu' => 'addUser', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '添加用户');
|
||||
$lang->tutorial->tasks['createAccount']['desc'] = "<p>在系统创建一个新的用户账号:</p><ul><li data-target='nav'>打开 <span class='task-nav'>组织 <i class='icon icon-angle-right'></i> 用户 <i class='icon icon-angle-right'></i> 添加用户</span> 页面;</li><li data-target='form'>在添加用户表单中填写新用户信息;</li><li data-target='submit'>保存用户信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProduct'] = array('title' => '创建产品');
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => 'create', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>在系统创建一个新的产品:</p><ul><li>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 添加产品</span> 页面;</li><li>在添加产品表单中填写要创建的产品信息;</li><li>保存产品信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => 'create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '新增产品');
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>在系统创建一个新的产品:</p><ul><li data-target='nav'>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 添加产品</span> 页面;</li><li data-target='form'>在添加产品表单中填写要创建的产品信息;</li><li data-target='submit'>保存产品信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createStory'] = array('title' => '创建需求');
|
||||
$lang->tutorial->tasks['createStory']['nav'] = array('module' => 'story', 'method' => 'create', 'menu' => 'story', 'feature' => '.create-story-btn', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>在系统创建一个新的需求:</p><ul><li>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 添加需求</span> 页面;</li><li>在添加需求表单中填写要创建的需求信息;</li><li>保存需求信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createStory']['nav'] = array('module' => 'story', 'method' => 'create', 'menuModule' => 'product', 'menu' => 'story', 'target' => '.create-story-btn', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提需求');
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>在系统创建一个新的需求:</p><ul><li data-target='nav'>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 添加需求</span> 页面;</li><li data-target='form'>在添加需求表单中填写要创建的需求信息;</li><li data-target='submit'>保存需求信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProject'] = array('title' => '创建项目');
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => 'create', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>在系统创建一个新的项目:</p><ul><li>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 添加项目</span> 页面;</li><li>在添加项目表单中填写要创建的 项目信息;</li><li>保存 项目信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => 'create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '添加项目');
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>在系统创建一个新的项目:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 添加项目</span> 页面;</li><li data-target='form'>在添加项目表单中填写要创建的 项目信息;</li><li data-target='submit'>保存 项目信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['linkStory'] = array('title' => '关联需求');
|
||||
$lang->tutorial->tasks['linkStory']['nav'] = array('module' => 'project', 'method' => 'linkStory', 'menu' => 'story', 'feature' => '.link-story-btn', 'form' => '#linkStoryForm', 'formType' => 'table', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>将需求关联到项目:</p><ul><li>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 关联需求</span> 页面;</li><li>在关联需求表单中勾选要关联的需求;</li><li>保存关联的需求信息。</li></ul>";
|
||||
$lang->tutorial->tasks['linkStory']['nav'] = array('module' => 'project', 'method' => 'linkStory', 'menu' => 'story', 'target' => '.link-story-btn', 'form' => '#linkStoryForm', 'formType' => 'table', 'submit' => '#submit', 'targetPageName' => '关联需求');
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>将需求关联到项目:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 关联需求</span> 页面;</li><li data-target='form'>在关联需求表单中勾选要关联的需求;</li><li data-target='submit'>保存关联的需求信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createTask'] = array('title' => '分解任务');
|
||||
$lang->tutorial->tasks['createTask']['nav'] = array('module' => 'task', 'method' => 'create', 'menu' => 'story', 'target' => '.btn-task-create', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>将项目需求分解为任务:</p><ul><li>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 分解任务</span> 页面;</li><li>在创建任务表单中填写任务信息;</li><li>保存任务信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createTask']['nav'] = array('module' => 'task', 'method' => 'create', 'menuModule' => 'project', 'menu' => 'story', 'target' => '.btn-task-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '建任务');
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>将项目需求分解为任务:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求列表 <i class='icon icon-angle-right'></i> 分解任务</span> 页面;</li><li data-target='form'>在创建任务表单中填写任务信息;</li><li data-target='submit'>保存任务信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createBug'] = array('title' => '提Bug');
|
||||
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit');
|
||||
$lang->tutorial->tasks['createBug']['desc'] = "<p>在系统中提交一个Bug:</p><ul><li>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> Bug列表 <i class='icon icon-angle-right'></i> 提Bug</span> 页面,或者打开 <span class='task-nav'> 测试 <i class='icon icon-angle-right'></i> Bug列表 <i class='icon icon-angle-right'></i> 提Bug</span>;</li><li>在创建任务表单中填写任务信息;</li><li>保存任务信息。</li></ul>";
|
||||
|
||||
foreach ($lang->tutorial->tasks as $name => $task) $lang->tutorial->tasks[$name]['name'] = $name;
|
||||
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提Bug');
|
||||
$lang->tutorial->tasks['createBug']['desc'] = "<p>在系统中提交一个Bug:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> Bug列表 <i class='icon icon-angle-right'></i> 提Bug</span> 页面,或者打开 <span class='task-nav'> 测试 <i class='icon icon-angle-right'></i> Bug列表 <i class='icon icon-angle-right'></i> 提Bug</span>;</li><li data-target='form'>在创建任务表单中填写任务信息;</li><li data-target='submit'>保存任务信息。</li></ul>";
|
||||
|
||||
@@ -11,38 +11,19 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
var formatSetting = function()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
var tasks = $.parseJSON('<?php echo json_encode(array_values($lang->tutorial->tasks), JSON_HEX_QUOT | JSON_HEX_APOS) ?>');
|
||||
console.log(tasks);
|
||||
var current = '<?php echo $current ?>';
|
||||
var setting = '<?php echo $setting ?>';
|
||||
|
||||
var $tasks = $('#tasks');
|
||||
|
||||
var updateTasks = function()
|
||||
{
|
||||
$tasks.empty();
|
||||
$.each(tasks, function(idx, task)
|
||||
{
|
||||
var $li = $('<li/>');
|
||||
var $a = $('<a href="###" />');
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<?php js::import($jsRoot . 'misc/base64.js'); ?>
|
||||
<?php $referer = $referer ? $referer : helper::createLink('my', 'index', '', 'tutorial') ?>
|
||||
<div id='pageContainer'>
|
||||
<div id='iframeWrapper'>
|
||||
<iframe id='iframePage' name='iframePage' src='<?php echo helper::createLink('my', 'index') ?>' frameborder='no' allowtransparency='true' scrolling='auto' hidefocus='' style='width: 100%; height: 100%; left: 0; top: 0'></iframe>
|
||||
<iframe id='iframePage' name='iframePage' src='<?php echo $referer ?>' frameborder='no' allowtransparency='true' scrolling='auto' hidefocus='' style='width: 100%; height: 100%; left: 0; top: 0'></iframe>
|
||||
<div id='taskModalBack'></div>
|
||||
<div id='taskModal'>
|
||||
<div class='finish-all'>
|
||||
<div class='start-icon'><i class='icon icon-certificate icon-spin icon-back'></i><i class='icon icon-check icon-front'></i></div>
|
||||
<h3><?php echo $lang->tutorial->congratulation ?></h3>
|
||||
<button type='button' class='btn btn-success'><i class="icon icon-repeat"></i> <?php echo $lang->tutorial->restart ?></button> <a href='<?php echo $referer ?>' class='btn btn-success'><i class="icon icon-signout"></i> <?php echo $lang->tutorial->exit ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='sidebar'>
|
||||
<header>
|
||||
@@ -52,36 +33,347 @@ $(function()
|
||||
<a data-toggle='tooltip' data-placement='left' title='<?php echo $lang->tutorial->exit ?>' href='<?php echo helper::createLink('my', 'index') ?>' class='btn btn-sm'><i class="icon icon-signout"></i></a>
|
||||
</div>
|
||||
</header>
|
||||
<section id='finish'>
|
||||
<div class='start-icon'><i class='icon icon-certificate icon-spin icon-back'></i><i class='icon icon-check icon-front'></i></div>
|
||||
<h3><?php echo $lang->tutorial->congratulation ?></h3>
|
||||
<button type='button' class='btn btn-success'><i class="icon icon-repeat"></i> <?php echo $lang->tutorial->restart ?></button> <a href='<?php echo helper::createLink('my', 'index') ?>' class='btn btn-success'><i class="icon icon-signout"></i> <?php echo $lang->tutorial->exit ?></a>
|
||||
</section>
|
||||
<section id='current'>
|
||||
<h4><?php echo $lang->tutorial->currentTask ?></h4>
|
||||
<div class='panel finish' id='task'>
|
||||
<div class='panel' id='task'>
|
||||
<div class='panel-heading'>
|
||||
<strong class='task-name task-name-current'>1. 创建账号</strong>
|
||||
<strong><span class='task-id-current'>1</span>. <span class='task-name task-name-current'></span></strong>
|
||||
<i class="icon icon-check pull-right"></i>
|
||||
</div>
|
||||
<div class='panel-body'></div>
|
||||
<div class='panel-body'>
|
||||
<div class='task-desc'></div>
|
||||
<a href='javascript:;' id='openTaskPage' class='btn-open-target-page'>
|
||||
<div class='normal'><i class="icon icon-flag-alt"></i> <?php echo $lang->tutorial->openTargetPage ?></div>
|
||||
<div class='opened'><i class="icon icon-flag"></i> <?php echo $lang->tutorial->atTargetPage ?></div>
|
||||
<div class='reload'><i class="icon icon-repeat"></i> <?php echo $lang->tutorial->reloadTargetPage ?></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class='clearfix actions'>
|
||||
<button type='button' class='btn btn-sm btn-prev-task'><i class="icon icon-angle-left"></i> <?php echo $lang->tutorial->previous ?></button>
|
||||
<button type='button' class='btn btn-primary btn-sm pull-right btn-next-task'><?php echo $lang->tutorial->nextTask ?> <i class="icon icon-angle-right"></i></button>
|
||||
<button type='button' class='btn btn-sm btn-prev-task btn-task'><i class="icon icon-angle-left"></i> <?php echo $lang->tutorial->previous ?></button>
|
||||
<button type='button' class='btn btn-primary btn-sm pull-right btn-task btn-next-task'><?php echo $lang->tutorial->nextTask ?> <i class="icon icon-angle-right"></i></button>
|
||||
</div>
|
||||
</section>
|
||||
<section id='all'>
|
||||
<h4><?php echo $lang->tutorial->allTasks ?> (<span class='task-num-current'>2</span>/<span class='tasks-count'>8</span>)</h4>
|
||||
<h4><?php echo $lang->tutorial->allTasks ?> (<span class='task-num-finish'>2</span>/<span class='tasks-count'><?php echo count($lang->tutorial->tasks) ?></span>)</h4>
|
||||
<div class='progress' id='tasksProgress'>
|
||||
<div class='progress-bar' style='width: 40%'>
|
||||
</div>
|
||||
</div>
|
||||
<ul id='tasks' class='nav nav-primary nav-stacked'>
|
||||
<li class='finish'><a href="#"><span>1</span>. <span class='task-name'></span><i class="icon icon-check pull-right"></i></a></li>
|
||||
<?php
|
||||
$idx = 1;
|
||||
$tasks = array();
|
||||
?>
|
||||
<?php foreach ($lang->tutorial->tasks as $name => $task):?>
|
||||
<?php
|
||||
$nav = $task['nav'];
|
||||
$task['name'] = $name;
|
||||
$task['id'] = $idx+1;
|
||||
$task['url'] = helper::createLink($nav['module'], $nav['method'], isset($nav['vars']) ? $nav['vars'] : '', 'tutorial');
|
||||
$tasks[$name] = $task;
|
||||
?>
|
||||
<li data-name='<?php echo $name; ?>'><a class='btn-task' href='javascript:;' data-name='<?php echo $name; ?>'><span><?php echo $idx++; ?></span>. <span class='task-name'><?php echo $task['title'] ?></span><i class='icon icon-check pull-right'></i></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
var formatSetting = function(str)
|
||||
{
|
||||
var settings = {};
|
||||
if(typeof str === 'string')
|
||||
{
|
||||
$.each(str.split(','), function(idx, name)
|
||||
{
|
||||
if(name) settings[name] = true;
|
||||
});
|
||||
}
|
||||
return settings;
|
||||
};
|
||||
|
||||
var tasks = $.parseJSON('<?php echo json_encode($tasks, JSON_HEX_QUOT | JSON_HEX_APOS) ?>');
|
||||
var current = '<?php echo $current ?>';
|
||||
var setting = formatSetting('<?php echo $setting ?>');
|
||||
var lang =
|
||||
{
|
||||
tagetPageTip: '<?php echo $lang->tutorial->tagetPageTip ?>',
|
||||
target : '<?php echo $lang->tutorial->taget ?>'
|
||||
}
|
||||
|
||||
console.log('TASKS', tasks);
|
||||
console.log('SETTING', setting);
|
||||
|
||||
var $tasks = $('#tasks'),
|
||||
$task = $('#task'),
|
||||
$openTaskPage = $('#openTaskPage'),
|
||||
$finish = $('#finish');
|
||||
var totalCount = $tasks.length;
|
||||
|
||||
var iWindow = window.frames['iframePage'];
|
||||
var iframe = $('#iframePage').get(0);
|
||||
var checkTaskId = null;
|
||||
var $lastTooltip;
|
||||
|
||||
var highlight = function($e, callback)
|
||||
{
|
||||
$e = $e.first();
|
||||
$e.closest('body').find('.hl-tutorial').removeClass('hl-tutorial hl-in');
|
||||
$e.addClass('hl-tutorial').parent().css('overflow', 'visible');
|
||||
setTimeout(function() {$e.addClass('hl-in'); callback && callback()}, 50);
|
||||
};
|
||||
|
||||
var finishTask = function()
|
||||
{
|
||||
$task.addClass('finish').find('[data-target]').removeClass('active').addClass('finish');
|
||||
alert('you finish task: ' + JSON.stringify(task));
|
||||
};
|
||||
|
||||
var showToolTip = function($e, text, options)
|
||||
{
|
||||
options = $.extend(
|
||||
{
|
||||
trigger: 'manual',
|
||||
title: text,
|
||||
placement: 'top',
|
||||
container: 'body',
|
||||
tipClass: 'tooltip-warning'
|
||||
}, options);
|
||||
$e = $e.first();
|
||||
if($lastTooltip) $lastTooltip.tooltip('hide');
|
||||
$lastTooltip = $e;
|
||||
if(!$e.data('zui.tooltip')) $e.addClass('tooltip-tutorial').attr('data-toggle', 'tooltip').tooltip(options)
|
||||
$e.tooltip('show');
|
||||
};
|
||||
|
||||
var checkTask = function()
|
||||
{
|
||||
if(!(iWindow && iWindow.config && iWindow.$))
|
||||
{
|
||||
checkTaskId = setTimeout(checkTask, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
if(checkTaskId) clearTimeout(checkTaskId);
|
||||
|
||||
var task = tasks[current];
|
||||
var $$ = iWindow.$;
|
||||
var pageConfig = iWindow.config;
|
||||
var targetStatus = status || {},
|
||||
$navTarget = $task.find('[data-target="nav"]').removeClass('active'),
|
||||
$formTarget = $task.find('[data-target="form"]').removeClass('active'),
|
||||
$submitTarget = $task.find('[data-target="submit"]').removeClass('active');
|
||||
targetStatus.nav = task.nav['module'].toLowerCase() === pageConfig.currentModule.toLowerCase() && task.nav['method'].toLowerCase() === pageConfig.currentMethod.toLowerCase();
|
||||
|
||||
if(targetStatus.nav)
|
||||
{
|
||||
// check form target
|
||||
var $form = $$(task.nav.form);
|
||||
var $formWrapper = $form.closest('.container');
|
||||
if(!$formWrapper.length) $formWrapper = $form;
|
||||
highlight($formWrapper);
|
||||
showToolTip($formWrapper, $formTarget.text());
|
||||
var fieldSelector = '';
|
||||
|
||||
if(task.nav.formType === 'table')
|
||||
{
|
||||
fieldSelector = ':checkbox:not(.rows-selector)';
|
||||
var $checkboxes = $form.find(fieldSelector);
|
||||
targetStatus.form = $checkboxes.filter(':checked').length > 0;
|
||||
if(!targetStatus.form) {
|
||||
targetStatus.waitFeild = $checkboxes.filter(':not(:checked):first').closest('td');
|
||||
}
|
||||
}
|
||||
else if(pageConfig.requiredFields)
|
||||
{
|
||||
targetStatus.form = true;
|
||||
var requiredFields = pageConfig.requiredFields.split(',');
|
||||
$.each(requiredFields, function(idx, requiredId)
|
||||
{
|
||||
fieldSelector += ',' + '#' + requiredId;
|
||||
var $required = $$('#' + requiredId);
|
||||
console.log('check', requiredId, $required.val(), $required);
|
||||
if($required.length)
|
||||
{
|
||||
var val = $required.val();
|
||||
if(val === undefined || val === null || val === '')
|
||||
{
|
||||
targetStatus.form = false;
|
||||
targetStatus.waitFeild = $required;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(fieldSelector.length > 1) fieldSelector = fieldSelector.substring(1);
|
||||
}
|
||||
|
||||
if(!$form.data('bindCheckTaskEvent'))
|
||||
{
|
||||
$form.off('submit .tutorial');
|
||||
$form.on('change.tutorial', fieldSelector, checkTask);
|
||||
var onSubmit = function(e)
|
||||
{
|
||||
var status = checkTask();
|
||||
if(!status.submitOK)
|
||||
{
|
||||
if(status.waitFeild)
|
||||
{
|
||||
highlight(status.waitFeild, function() {
|
||||
setTimeout(function() {
|
||||
highlight($formWrapper);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
finishTask();
|
||||
}
|
||||
}
|
||||
if(task.nav.submit) $form.on('click.tutorial', task.nav.submit, onSubmit);
|
||||
else $form.submit(onSubmit);
|
||||
}
|
||||
|
||||
if(targetStatus.form)
|
||||
{
|
||||
$submitTarget.addClass('active');
|
||||
if(task.nav.submit) showToolTip($form.find(task.nav.submit), $submitTarget.text());
|
||||
}
|
||||
else
|
||||
{
|
||||
$formTarget.addClass('active');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check nav target
|
||||
$navTarget.addClass('active');
|
||||
var menuModule = task.nav.menuModule || task.nav['module'];
|
||||
var $mainmenu = $$('#mainmenu');
|
||||
var $mainmenuItem = $mainmenu.find('[data-id="' + menuModule + '"]');
|
||||
var tagetPageTip = lang.tagetPageTip.replace('%s', task.nav.targetPageName || lang.target);
|
||||
if(!$mainmenuItem.hasClass('active'))
|
||||
{
|
||||
highlight($mainmenuItem);
|
||||
showToolTip($mainmenuItem, tagetPageTip);
|
||||
}
|
||||
else if(task.nav.menu)
|
||||
{
|
||||
var $modulemenu = $$('#modulemenu');
|
||||
var $modulemenuItem = $modulemenu.find('[data-id="' + task.nav.menu + '"]');
|
||||
if(!$modulemenuItem.hasClass('active'))
|
||||
{
|
||||
highlight($modulemenuItem);
|
||||
showToolTip($modulemenuItem, tagetPageTip);
|
||||
}
|
||||
else if(task.nav.target)
|
||||
{
|
||||
var $targetItem = $$(task.nav.target);
|
||||
highlight($targetItem);
|
||||
showToolTip($targetItem, tagetPageTip);
|
||||
}
|
||||
}
|
||||
}
|
||||
$navTarget.toggleClass('finish', !!targetStatus.nav);
|
||||
$formTarget.toggleClass('finish', !!targetStatus.form);
|
||||
$submitTarget.toggleClass('finish', !!targetStatus.submit);
|
||||
$openTaskPage.toggleClass('open', targetStatus.nav);
|
||||
|
||||
targetStatus.submitOK = targetStatus.nav && targetStatus.form;
|
||||
return targetStatus;
|
||||
};
|
||||
|
||||
var onIframeLoad = function()
|
||||
{
|
||||
iWindow = window.frames['iframePage'];
|
||||
checkTask();
|
||||
var title = (iWindow.$ ? iWindow.$('head > title').text() : '') + $('head > title').text();
|
||||
var url = createLink('tutorial', 'index', 'referer=' + Base64.encode(iWindow.location.href) + '&task=' + current);
|
||||
window.history.replaceState({}, title, url);
|
||||
};
|
||||
|
||||
var openIframePage = function(url)
|
||||
{
|
||||
url = url || tasks[current].url;
|
||||
console.log('open', url);
|
||||
try
|
||||
{
|
||||
iWindow.location.replace(url);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
iframe.get(0).src = url;
|
||||
}
|
||||
};
|
||||
|
||||
var showTask = function(taskName)
|
||||
{
|
||||
taskName = taskName || current;
|
||||
current = taskName;
|
||||
|
||||
if(!taskName) return;
|
||||
var task = tasks[taskName];
|
||||
if(!task) return;
|
||||
|
||||
var $li = $tasks.children('li').removeClass('active').filter('[data-name="' + taskName + '"]').addClass('active');
|
||||
$task.find('.task-name-current').text(task.title);
|
||||
$task.find('.task-id-current').text(task.id);
|
||||
$task.toggleClass('finish', task.finish);
|
||||
$task.find('.task-desc').html(task.desc).find('.task-nav').addClass('btn-open-target-page');
|
||||
$task.find('.task-page-name').text(task.nav.targetPageName || lang.target);
|
||||
|
||||
var $prev = $li.prev('li'), $next = $li.next('li');
|
||||
$('.btn-prev-task').toggleClass('hidden', !$prev.length).data('name', $prev.data('name'));
|
||||
$('.btn-next-task').toggleClass('hidden', !$next.length).data('name', $next.data('name'));
|
||||
checkTask();
|
||||
};
|
||||
|
||||
var updateUI = function()
|
||||
{
|
||||
var currentTask, finishCount = 0;
|
||||
|
||||
$tasks.children('li').each(function(idx)
|
||||
{
|
||||
var $li = $(this);
|
||||
var name = $li.data('name');
|
||||
var task = tasks[name];
|
||||
var finish = !!setting[name];
|
||||
task.id = idx + 1;
|
||||
task.finish = finish;
|
||||
finishCount += finish ? 1 : 0;
|
||||
|
||||
$li.toggleClass('finish', finish);
|
||||
if(!current && !finish) current = name;
|
||||
});
|
||||
|
||||
$finish.toggleClass('show', finishCount >= totalCount);
|
||||
$('.task-num-finish').text(finishCount);
|
||||
|
||||
showTask(current);
|
||||
};
|
||||
|
||||
updateUI();
|
||||
|
||||
$(document).on('click', '.btn-task', function()
|
||||
{
|
||||
showTask($(this).data('name'));
|
||||
}).on('click', '.btn-open-target-page', function()
|
||||
{
|
||||
openIframePage();
|
||||
});
|
||||
|
||||
iframe.onload = iframe.onreadystatechange = function()
|
||||
{
|
||||
if (this.readyState && this.readyState != 'complete') return;
|
||||
onIframeLoad();
|
||||
};
|
||||
|
||||
iWindow.onload = onIframeLoad;
|
||||
});
|
||||
</script>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// https://github.com/dankogai/js-base64
|
||||
(function(global){"use strict";var _Base64=global.Base64;var version="2.1.9";var buffer;if(typeof module!=="undefined"&&module.exports){try{buffer=require("buffer").Buffer}catch(err){}}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++)t[bin.charAt(i)]=i;return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?fromCharCode(192|cc>>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][-¿]","[à-ï][-¿]{2}","[ð-÷][-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/[\s\S]{1,4}/g,cb_decode)};var _decode=buffer?function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}})(this);
|
||||
@@ -724,3 +724,7 @@ body {font-size: 13px; color:#141414;padding-bottom: 40px;}
|
||||
#mainmenu .nav > li > a > .icon-remove:hover {color: #666}
|
||||
#helpContent .load-error {padding: 20px; display: none}
|
||||
#helpContent.show-error .load-error {display: block}
|
||||
|
||||
.hl-tutorial {position: relative!important; z-index: 1010!important; box-shadow: 0 0 0 0px rgba(0,0,0,0)!important; transition: box-shadow 2s cubic-bezier(.175,.885,.32,1)!important;}
|
||||
.hl-tutorial.hl-in {box-shadow: 0 0 20px 0 #FFF0D5, 0 0 0 2px #F1A325, 0 0 0 2000px rgba(0,0,0,.2)!important}
|
||||
.hl-tutorial.hl-in:hover {box-shadow: 0 0 30px 0 #FFF0D5, 0 0 0 5px #F1A325, 0 0 0 2000px rgba(0,0,0,.3)!important}
|
||||
|
||||
Reference in New Issue
Block a user