index.html.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. /**
  3. * The trash view file of action module of ZenTaoPMS.
  4. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.zentao.net)
  5. * @license ZPL(https://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  6. * @author Wang XuePeng <wangxuepeng@easycorp.ltd>
  7. * @package tutorial
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. /* 使用 pagebase 渲染页面并启用 ZUI。 Render page with "pagebase" and enabled zui framework. */
  12. set::zui(true);
  13. /* 将所有教程按类型进行分组。Grouped all guides by type. */
  14. $groupedGuides = array();
  15. $currentType = 'starter'; // 当前选中的类型。Current active type.
  16. $guideIndex = 0;
  17. foreach($guides as $guideName => $guide)
  18. {
  19. $taskIndex = 0;
  20. $guide->index = $guideIndex++;
  21. $guide->taskList = array();
  22. foreach($guide->tasks as $tasID => $task)
  23. {
  24. $task['index'] = $taskIndex++;
  25. foreach($task['steps'] as $index => $step)
  26. {
  27. $step['index'] = $index;
  28. $step['guideName'] = $guideName;
  29. $step['taskName'] = $task['name'];
  30. $task['steps'][$index] = $step;
  31. }
  32. $guide->tasks[$tasID] = $task;
  33. $guide->taskList[] = $task['name'];
  34. }
  35. $groupedGuides[$guide->type][$guideName] = $guide;
  36. if($currentTask === $guideName || strncmp($currentTask, "$guideName.", strlen("$guideName.")) === 0) $currentType = $guide->type;
  37. }
  38. $buildStepItem = function(array $step, int $index)
  39. {
  40. return li(setClass('tutorial-step pl-1'), setData('step', $index), div
  41. (
  42. setClass('tutorial-step-title flex items-center h-6 border-l px-2 text-gray'),
  43. $step['title']
  44. ));
  45. };
  46. /**
  47. * 生成任务列表(simpleList)条目。
  48. * Build configuration of simpleList item for tasks.
  49. *
  50. * @param array $task 任务配置。Task configuration.
  51. * @param string $taskName 任务键。Task key.
  52. * @return node
  53. */
  54. $buildTaskItem = function(array $task, string $taskName) use ($lang, $buildStepItem)
  55. {
  56. return li
  57. (
  58. setClass('tutorial-task mt-2'),
  59. setData('name', $taskName),
  60. setData('status', 'wait'),
  61. div
  62. (
  63. setClass('tutorial-task-item row items-center gap-2 canvas h-8 cursor-pointer'),
  64. div($task['title'], setClass('tutorial-task-title flex-auto')),
  65. div
  66. (
  67. setClass('tutorial-task-actions flex-none row items-center'),
  68. btn
  69. (
  70. span($lang->tutorial->start, setData('type', 'start')),
  71. span($lang->tutorial->restart, setData('type', 'restart')),
  72. span($lang->tutorial->continue, setData('type', 'continue')),
  73. setClass('size-sm tutorial-task-start')
  74. )
  75. )
  76. ),
  77. div
  78. (
  79. setClass('tutorial-task-steps pt-1'),
  80. simpleList
  81. (
  82. setClass('tutorial-step-list'),
  83. set::items($task['steps']),
  84. set::onRenderItem($buildStepItem)
  85. )
  86. )
  87. );
  88. };
  89. /**
  90. * 生成教程指南列表(simpleList)条目。
  91. * Build configuration of simpleList item for tutorial guides.
  92. *
  93. * @param object $guide 指南对象。Guide object.
  94. * @param string $guideName 指南键。Guide guideName.
  95. * @return node
  96. */
  97. $buildGuideItem = function($guide, string $guideName) use ($buildTaskItem)
  98. {
  99. return li
  100. (
  101. setClass('tutorial-guide mb-2.5'),
  102. setData('name', $guideName),
  103. div
  104. (
  105. setClass('tutorial-guide-item row items-center gap-2 canvas h-10 cursor-pointer border rounded-sm px-2.5 hover:shadow group'),
  106. icon($guide->icon, setClass('tutorial-guide-icon flex-none')),
  107. div($guide->title, setClass('tutorial-guide-title flex-auto text-md')),
  108. icon('import rotate-270 primary-pale rounded-full w-5 h-5 center opacity-0 group-hover:opacity-100 tutorial-guide-trailing-icon')
  109. ),
  110. div
  111. (
  112. setClass('tutorial-guide-tasks'),
  113. simpleList
  114. (
  115. setClass('tutorial-task-list'),
  116. set::items($guide->tasks),
  117. set::onRenderItem($buildTaskItem)
  118. )
  119. )
  120. );
  121. };
  122. /**
  123. * 生成教程选项卡面板(tabPane)配置。
  124. * Build configuration of tabPane for tutorial.
  125. *
  126. * @param string $type 任务类型。Task type.
  127. * @return tabPane
  128. */
  129. $buildTutorialTabPane = function($type) use ($groupedGuides, $lang, $currentType, $buildGuideItem)
  130. {
  131. $guides = $groupedGuides[$type];
  132. return tabPane
  133. (
  134. set::title($lang->tutorial->guideTypes[$type]),
  135. set::active($type === $currentType),
  136. set::class('px-2.5'),
  137. set::key($type),
  138. simpleList
  139. (
  140. setData('type', $type),
  141. setClass('tutorial-guide-list', ($type == 'starter' && is_array($guides) && count($guides) === 1) ? 'is-single-guide' : ''),
  142. set::items($guides),
  143. set::onRenderItem($buildGuideItem)
  144. )
  145. );
  146. };
  147. jsVar('guides', $guides);
  148. jsVar('lang', array
  149. (
  150. 'colon' => $lang->colon,
  151. 'nextGuide' => $lang->tutorial->nextGuide,
  152. 'nextTask' => $lang->tutorial->nextTask,
  153. 'nextStep' => $lang->tutorial->nextStep,
  154. 'exitStep' => $lang->tutorial->exitStep,
  155. 'finish' => $lang->tutorial->finish,
  156. 'clickTipFormat' => $lang->tutorial->clickTipFormat,
  157. 'clickAndOpenIt' => $lang->tutorial->clickAndOpenIt,
  158. 'congratulateTask' => $lang->tutorial->congratulateTask
  159. ));
  160. div
  161. (
  162. setID('pageContainer'),
  163. setCssVar('--sidebar-width', '240px'), // 侧边栏宽度。Sidebar width.
  164. setClass('canvas absolute left-0 top-0 right-0 bottom-0 overflow-hidden'),
  165. div
  166. (
  167. setID('iframeWrapper'), // 应用页面容器。App iframe container.
  168. setClass('absolute left-0 top-0 bottom-0'),
  169. style::right('--sidebar-width'),
  170. h::iframe
  171. (
  172. setID('iframePage'),
  173. setClass('w-full h-full border-none'),
  174. set::name('iframePage'),
  175. set::src(createLink('index', 'index'))
  176. )
  177. ),
  178. div
  179. (
  180. setID('sidebar'), // 侧边栏。Sidebar.
  181. setClass('absolute top-0 bottom-0 right-0 border-l', count($groupedGuides) === 1 ? 'is-single-type-mode' : ''),
  182. style::width('--sidebar-width'),
  183. ($currentGuide && $currentTask) ? on::init()->call('activeTask', $currentGuide, $currentTask) : null,
  184. h::header
  185. (
  186. setClass('row items-center flex-nowrap p-2'),
  187. h2
  188. (
  189. $lang->tutorial->common,
  190. setClass('flex-auto text-xl')
  191. ),
  192. div
  193. (
  194. setClass('flex-none'),
  195. btn
  196. (
  197. setClass('size-sm'),
  198. set::type('ghost'),
  199. set::url(inlink('quit')),
  200. set::hint($lang->tutorial->exit),
  201. set::icon('close')
  202. )
  203. )
  204. ),
  205. tabs
  206. (
  207. setID('tutorialTabs'),
  208. set::headerClass('px-2.5'),
  209. array_map($buildTutorialTabPane, array_keys($lang->tutorial->guideTypes)),
  210. on::click('.tutorial-task-start')->do('handleClickTask(event)'),
  211. on::click('.tutorial-guide-item')->do('handleClickGuide(event)')
  212. )
  213. )
  214. );
  215. render('pagebase');