ajaxgethome.html.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. /**
  3. * The api home file of api module of ZenTaoPMS.
  4. * @copyright Copyright 2024 禅道软件(青岛)有限公司(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 Sun Hao<sunhao@easycorp.ltd>
  7. * @package api
  8. * @link https://www.zentao.net
  9. */
  10. namespace zin;
  11. $libColors = array('var(--color-secondary-500)', 'var(--color-primary-500)', 'var(--color-warning-500)', 'var(--color-success-500)', 'var(--color-special-500)');
  12. $isNolink = $type == 'nolink';
  13. $isEmpty = $isNolink ? empty($libs) : empty($programs);
  14. $canCreateLib = hasPriv('api', 'createLib');
  15. $canEditLib = hasPriv('api', 'editLib');
  16. $canDeleteLib = hasPriv('api', 'deleteLib');
  17. $showLibAction = $isNolink ? ($canEditLib || $canDeleteLib) : $canCreateLib;
  18. /* Create load home command statement. */
  19. $createCommand = function(array $args) use($pager, $type, $unclosed, $notempty)
  20. {
  21. $args = array_merge(array('type' => $type, 'unclosed' => $unclosed, 'notempty' => $notempty, 'recPerPage' => $pager->recPerPage, 'pageID' => $pager->pageID), $args);
  22. $parts = array('loadHome');
  23. $parts[] = $args['type'];
  24. $params = array();
  25. if($args['notempty']) $params[] = 'notempty';
  26. if($args['unclosed']) $params[] = 'unclosed';
  27. $parts[] = implode('_', $params);
  28. $parts[] = $args['recPerPage'];
  29. $parts[] = $args['pageID'];
  30. return implode('/', $parts);
  31. };
  32. $buildLibItem = function(int $id, string $name, int $count = 0) use ($libColors, $type, $isNolink, $showLibAction, $lang)
  33. {
  34. return div
  35. (
  36. setClass('doc-space-card-lib p-1.5 w-1/5 group'),
  37. setKey($id),
  38. div
  39. (
  40. setClass('canvas border rounded py-2 px-3 col gap-1 hover:shadow-lg hover:border-primary relative cursor-pointer'),
  41. set('zui-command', $isNolink ? "selectSpace/nolink/$id" : "selectSpace/$type.$id/_first"),
  42. icon($isNolink ? 'interface-lib' : $type, setClass('text-2xl'), $isNolink ? setStyle('color', $libColors[$id % count($libColors)]) : setClass('text-gray')),
  43. div(setClass('font-bold text-clip'), set::title($name), $name),
  44. div(setClass('text-gray text-sm'), $count ? sprintf($lang->api->apiTotalInfo, $count) : $lang->api->noApi),
  45. $showLibAction ? div
  46. (
  47. setClass('toolbar absolute top-1 right-1 opacity-0 group-hover:opacity-100'),
  48. btn
  49. (
  50. setClass('doc-space-lib-btn'),
  51. set('zui-command', "showHomeItemMenu/$type/$id"),
  52. set::icon('ellipsis-v'),
  53. set::size('sm'),
  54. set::type('ghost')
  55. )
  56. ) : null
  57. )
  58. );
  59. };
  60. $buildProgramItem = function($program) use ($type, $buildLibItem, $lang)
  61. {
  62. $items = array();
  63. if($type === 'product' && !empty($program->products))
  64. {
  65. foreach($program->products as $product) $items[] = $buildLibItem($product->id, $product->name, isset($product->apiCount) ? $product->apiCount : 0);
  66. }
  67. if($type === 'project' && !empty($program->projects))
  68. {
  69. foreach($program->projects as $project) $items[] = $buildLibItem($project->id, $project->name, isset($project->apiCount) ? $project->apiCount : 0);
  70. }
  71. return div
  72. (
  73. setClass('doc-space-card ring rounded surface-light'),
  74. setKey($program->id),
  75. div
  76. (
  77. setClass('row items-center justify-between gap-2 px-2.5 py-1 border-b'),
  78. div(setClass('row items-center gap-2 flex-none'), icon('program', setClass('text-gray flex-none')), div(setClass('min-w-0 flex-auto'), strong($program->name)))
  79. ),
  80. div
  81. (
  82. setClass('doc-space-card-libs p-1.5'),
  83. empty($items) ? div(setClass('h-24 center text-gray'), $lang->noData) : div(setClass('row flex-wrap'), $items)
  84. )
  85. );
  86. };
  87. $filterItems = array();
  88. foreach($lang->api->homeFilterTypes as $key => $text)
  89. {
  90. $item = array('text' => $text, 'zui-command' => $createCommand(array('type' => $key)));
  91. if($key === $type)
  92. {
  93. $count = $isNolink ? count($libs) : count($programs);
  94. $item['active'] = true;
  95. $item['badge'] = wg(label(setClass('size-sm canvas ring-0 rounded-md'), $count));
  96. }
  97. $filterItems[] = $item;
  98. }
  99. div
  100. (
  101. setKey('header'),
  102. setClass('doc-app-header flex-none surface-light row items-center border-b py-1 pl-1 h-10 pr-2 gap-3 flex-none'),
  103. nav
  104. (
  105. setClass('ml-2'),
  106. set::compact(),
  107. set::items($filterItems)
  108. ),
  109. checkbox(set::name('notempty'), set::text($lang->api->showNotEmpty), set::checked($notempty)),
  110. $type !== 'nolink' ? checkbox(set::name('showclosed'), set::text($lang->api->showClosed), set::checked(!$unclosed)) : null,
  111. div(setClass('flex-auto')),
  112. (!$isEmpty && $canCreateLib) ? btn
  113. (
  114. set::icon('plus'),
  115. set::type('primary'),
  116. set::size('md'),
  117. set::text($lang->api->createLib),
  118. set('zui-command', "createLib/$type")
  119. ) : null,
  120. on::change('[type=checkbox]')
  121. ->const('notempty', jsRaw('$this.closest(".doc-app-header").find("[name=notempty]:checked").length'))
  122. ->const('showclosed', jsRaw('$this.closest(".doc-app-header").find("[name=showclosed]:checked").length'))
  123. ->call('loadHome', $type, jsRaw('[notempty ? "notempty" : "", showclosed ? "" : "unclosed"].join("_")'))
  124. );
  125. $views = array();
  126. if($isEmpty)
  127. {
  128. $views = div
  129. (
  130. setKey('empty'),
  131. setClass('doc-app-empty h-full center gap-4'),
  132. div(setClass('text-gray'), $lang->api->noLib),
  133. $canCreateLib ? btn
  134. (
  135. set::icon('plus'),
  136. set::type('primary'),
  137. set::text($lang->api->createLib),
  138. set('zui-command', "createLib/$type")
  139. ) : null
  140. );
  141. }
  142. elseif($type === 'nolink')
  143. {
  144. foreach($libs as $lib) $views[] = $buildLibItem($lib->id, $lib->name, isset($lib->apiCount) ? $lib->apiCount : 0);
  145. $views = div
  146. (
  147. setClass('doc-space-card-libs'),
  148. setStyle('margin', '-8px'),
  149. div(setClass('row flex-wrap'), $views)
  150. );
  151. }
  152. else
  153. {
  154. foreach($programs as $program) $views[] = $buildProgramItem($program);
  155. }
  156. div
  157. (
  158. setKey('body'),
  159. setClass('doc-app-body flex-auto min-h-0 col gap-4 p-4 items-stretch overflow-auto scrollbar-hover no-morph'),
  160. $views
  161. );
  162. if(!$isEmpty)
  163. {
  164. div
  165. (
  166. setKey('footer'),
  167. setClass('doc-app-footer surface-light row items-center border-t py-1.5 px-2'),
  168. div(setClass('flex-auto')),
  169. pager
  170. (
  171. set(usePager()),
  172. set::useState(),
  173. set::onChangePageInfo(jsRaw('(info, event) => {event.preventDefault(); window.loadHome({pager: {recPerPage: info.recPerPage, page: info.page}});}'))
  174. )
  175. );
  176. }