ajaxgetdropmenuforold.html.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. <?php
  2. /**
  3. * The ajaxGetDropmenuForOld view file of message module of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
  6. * @license ZPL (http://zpl.pub/page/zplv12.html)
  7. * @author Yidong Wang <yidong@cnezsoft.com>
  8. * @package message
  9. * @version $Id$
  10. * @link http://www.zentao.net
  11. */
  12. $noDataHtml = "<div class='text-gray text-center nodata'>{$lang->noData}</div>";
  13. $browserSetting = $config->message->browser;
  14. $buildMessageList = function($messageGroup) use ($lang, $noDataHtml)
  15. {
  16. if(empty($messageGroup)) return $noDataHtml;
  17. $dateList = array();
  18. foreach($messageGroup as $date => $messages)
  19. {
  20. $itemList = array();
  21. foreach($messages as $message)
  22. {
  23. $isUnread = $message->status != 'read';
  24. $dotColor = $isUnread ? 'danger' : 'gray';
  25. $li = "<li class='message-item border rounded-lg p-2 mt-2" . ($isUnread ? ' unread' : '') . "' data-msgid='{$message->id}' style='word-break: break-all;' onclick='markRead(this)'>\n";
  26. $li .= "<div class='text-gray relative'>";
  27. $li .= "<div><span class='label label-dot mr-2 {$dotColor}'></span><span>{$lang->message->browser}</span></div>\n";
  28. $li .= "<div class='absolute' style='top:0px; right:0px;'><span>{$message->showTime}</span><i class='icon icon-close ml-2 cursor-pointer delete-message-btn' onclick='deleteMessage(this)'></i></div>\n";
  29. $li .= "</div>\n";
  30. $li .= "<div class='pt-1'>{$message->data}</div>\n";
  31. $li .= "</li>\n";
  32. $itemList[] = $li;
  33. }
  34. $dateList[] = "<li class='message-date mt-2'>{$date}\n <ul class='list-unstyled'>" . implode("\n", $itemList) . "</ul>";
  35. }
  36. return "<ul class='list-unstyled'>" . implode("\n", $dateList) . "</ul>";
  37. };
  38. ?>
  39. <style>
  40. #messageTabs.text-black {color: rgb(49, 60, 82);}
  41. #messageTabs.pt-10px {padding-top:10px;}
  42. #messageTabs.px-5 {padding-left: 20px; padding-right: 20px;}
  43. #messageTabs.pb-5 {padding-bottom: 20px;}
  44. #messageTabs .border {border-width: 1px; border-color: rgb(235, 237, 243); border-style: solid;}
  45. #messageTabs .rounded-lg {border-radius: 6px;}
  46. #messageTabs .p-2 {padding:8px;}
  47. #messageTabs .pt-2 {padding-top:8px;}
  48. #messageTabs .pl-2 { padding-left: 8px; }
  49. #messageTabs .pb-2 { padding-bottom: 8px; }
  50. #messageTabs .pt-2 { padding-top: 8px; }
  51. #messageTabs .mt-2 {margin-top:8px;}
  52. #messageTabs .mr-2 {margin-right:8px;}
  53. #messageTabs .ml-2 {margin-left:8px;}
  54. #messageTabs .cursor-pointer {cursor: pointer;}
  55. #messageTabs .tabs-header{border-bottom-width: 1px;}
  56. #messageTabs .label-dot{width:5px; height:5px; vertical-align: middle;}
  57. #messageTabs .label-dot.gray { background-color: rgb(100, 117, 139); box-shadow: rgb(255, 255, 255) 0px 0px 0px 0px, rgb(100, 117, 139) 0px 0px 0px 1px, rgba(0, 0, 0, 0) 0px 0px 0px 0px;}
  58. #messageTabs .w-52{width:208px;}
  59. #messageTabs .top-3{top:12px;}
  60. #messageTabs .right-5{right:20px;}
  61. #messageTabs .btn-link{background: 0 0; border-color:rgba(0, 0, 0, 0);}
  62. #messageTabs .w-5\/6 { width: 83.333333%; }
  63. #messageTabs .border-b { border-bottom: 1px solid rgb(235, 237, 243); }
  64. #messageTabs .font-bold { font-weight: 700; }
  65. #messageTabs .justify-center { justify-content: center; }
  66. #messageTabs #messageSettingDropdown { padding: 8px;}
  67. #messageTabs .message-item a[data-url]{color: rgb(43, 71, 162);}
  68. #messageTabs .form, #messageTabs .form-label { display: flex;}
  69. #messageTabs .form {flex-direction: column; gap: 4px;}
  70. #messageTabs .form-horz .form-group,
  71. #messageTabs .form-horz .form-row { align-items: flex-start; display: flex; flex-direction: row;}
  72. #messageTabs .form-horz .form-group { flex-grow: 1; flex-wrap: wrap; min-height: 32px; min-width: 0; padding-left: 96px; position: relative; }
  73. #messageTabs .form-horz .form-group.no-label { padding-left: 0; }
  74. #messageTabs .form-label { align-items: center; color: #3d4667; flex-direction: row; gap: 4px; height: 32px; overflow: hidden; position: relative; text-overflow: ellipsis; white-space: nowrap; }
  75. #messageTabs .form-horz .form-label { justify-content: flex-end; left: 0; padding-left: 16px; padding-right: 8px; position: absolute; top: 0; width: 96px; }
  76. .switch { display: flex; gap: .6px; min-height: 20px; padding-left: 40px; position: relative; }
  77. .switch>input { bottom: 0; left: 0; opacity: 0; position: absolute; right: 0; top: 0; }
  78. .switch>label:before { cursor: pointer; box-shadow:rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 2px 4px 0px inset; }
  79. .switch>label:after, .switch>label:before {
  80. border-radius: 9999px;
  81. border-width: 1px;
  82. height: 16px;
  83. left: 0;
  84. position: absolute;
  85. top: 2px;
  86. width: 32px;
  87. border-color: rgb(210, 214, 229);
  88. background-color: rgb(239, 241, 243);
  89. transition-duration: .3s;
  90. transition-property: all;
  91. transition-timing-function: cubic-bezier(.4,0,.2,1);
  92. content: "";
  93. }
  94. .switch>label:after {
  95. height: 12px;
  96. left: 2px;
  97. top: 4px;
  98. width: 12px;
  99. border-color: rgb(255, 255, 255);
  100. background-color: rgb(255, 255, 255);
  101. box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.04) 0px 3px 8px 0px, rgba(0, 0, 0, 0.01) 0px 1px 2px -1px;
  102. }
  103. .switch>input:checked+label:before { background-color: rgb(56, 131, 250); border-color: rgba(var(--color-inverse-rgb), .2); }
  104. .switch>label:hover:before { border-color: gba(235, 237, 243); }
  105. .switch>input:checked+label:after { color: #3883fa; left: 18px; }
  106. #header #dropdownMessageMenu{background-color: #fff; overflow-y: auto; max-height: calc(100vh - 50px); min-height: 280px;}
  107. </style>
  108. <div id='messageTabs' class='text-black pt-10px px-5 pb-5 relative' style='width:400px; background-color:#fff; color: rgb(49, 60, 82)'>
  109. <ul class="nav nav-tabs">
  110. <li class='<?php echo $active == 'unread' ? 'active' : '';?>'><a data-tab href="#unread-messages"><span><?php printf($lang->message->unread, $unreadCount)?></span></a></li>
  111. <li class='<?php echo $active == 'all' ? 'active' : '';?>'><a data-tab href="#all-messages"><span><?php echo $lang->message->all;?></span></a></li>
  112. </ul>
  113. <div class="tab-content" style='padding-top: 10px;'>
  114. <div class="tab-pane <?php echo $active == 'unread' ? 'active' : '';?>" id="unread-messages">
  115. <?php echo $buildMessageList($unreadMessages);?>
  116. </div>
  117. <div class="tab-pane <?php echo $active == 'all' ? 'active' : '';?>" id="all-messages">
  118. <?php echo $buildMessageList($allMessages);?>
  119. </div>
  120. </div>
  121. <div class="absolute top-3 right-5" style="z-index: 100;">
  122. <?php echo html::commonButton("", "title='{$lang->message->notice->allMarkRead}' onclick='markAllRead()'", 'allMarkRead btn btn-sm btn-link', 'clear');?>
  123. <?php echo html::commonButton("", "title='{$lang->message->notice->clearRead}' onclick='clearRead()'", 'clearRead btn btn-sm btn-link', 'trash');?>
  124. <span class='messageSettingBox relative'>
  125. <?php echo html::commonButton("", "id='messageSettingDropdown-toggle' title={$lang->message->browserSetting->more} onclick='toggleSettingDropdown()'", 'btn btn-sm btn-link', 'cog-outline');?>
  126. <div class="dropdown-menu w-52 absolute" id="messageSettingDropdown" style='left:-170px;top:25px;'>
  127. <form class="form ajaxForm form-horz" action="<?php echo inlink('ajaxSetOneself');?>" method="post">
  128. <div class="form-row font-bold border-b pb-2 pl-2 pt-2"><?php echo $lang->message->browserSetting->more;?></div>
  129. <div class="form-group" style="align-items: center;">
  130. <label class="form-label"><?php echo $lang->message->browserSetting->show;?></label>
  131. <div class="switch">
  132. <input type="checkbox" id="show_1" name="show" <?php echo $browserSetting->show ? "checked='checked'" : ''; ?> value="1">
  133. <label for="show_1">&nbsp; </label>
  134. </div>
  135. </div>
  136. <div class="form-group" style="align-items: center;">
  137. <label class="form-label"><?php echo $lang->message->browserSetting->count;?></label>
  138. <div class="switch">
  139. <input type="checkbox" id="count_1" name="count" <?php echo $browserSetting->count ? "checked='checked'" : ''; ?> value="1">
  140. <label for="count_1">&nbsp; </label>
  141. </div>
  142. </div>
  143. <div class="form-group w-5/6">
  144. <label class="form-label"><?php echo $lang->message->browserSetting->maxDays;?></label>
  145. <div class="input-control has-icon-right">
  146. <?php echo html::input('maxDays', $browserSetting->maxDays, "class='form-control'");?>
  147. <label for='maxDays' class="input-control-icon-right"><?php echo $lang->day;?></label>
  148. </div>
  149. </div>
  150. <div class="form-group justify-center form-actions mt-2 no-label">
  151. <?php echo html::submitButton($lang->save, "style='min-width:20px;'", "btn btn-sm btn-primary");?>
  152. <?php echo html::commonButton($lang->cancel, "style='min-width:20px;' onclick='closeSettingDropdown()'", "btn btn-sm");?>
  153. </div>
  154. </form>
  155. </div>
  156. </span>
  157. </div>
  158. </div>
  159. <?php
  160. js::set('unreadLangTempate', $lang->message->unread);
  161. js::set('noDataHtml', $noDataHtml);
  162. js::set('showCount', $config->message->browser->count);
  163. ?>
  164. <script>
  165. window.markRead = function(obj)
  166. {
  167. let $this = $(obj);
  168. if(!$this.hasClass('message-item')) $this = $this.closest('.message-item');
  169. let isUnread = $this.hasClass('unread');
  170. if(!isUnread) return;
  171. let messageID = $this.data("msgid");
  172. let $messageItem = $('#messageTabs .message-item.unread[data-msgid="' + messageID + '"]');
  173. $messageItem.find('.label-dot.danger').removeClass('danger').addClass('gray');
  174. $messageItem.removeClass('unread');
  175. $messageItem.attr('data-target', '#readContextMenu');
  176. $.get($.createLink('message', 'ajaxMarkRead', "id=" + messageID));
  177. /* Rerender unread count. */
  178. $('#messageTabs #unread-messages.tab-pane').find('.message-item[data-msgid="' + messageID + '"]').addClass('hidden');
  179. renderMessage();
  180. };
  181. window.markUnread = function(obj)
  182. {
  183. let $this = $(obj);
  184. if(!$this.hasClass('message-item')) $this = $this.closest('.message-item');
  185. let isUnread = $this.hasClass('unread');
  186. if(isUnread) return;
  187. let messageID = $this.data("msgid");
  188. let $messageItem = $('#messageTabs .message-item[data-msgid="' + messageID + '"]');
  189. $messageItem.find('.label-dot.gray').removeClass('gray').addClass('danger');
  190. $messageItem.addClass('unread');
  191. $.get($.createLink('message', 'ajaxMarkUnread', "id=" + messageID));
  192. /* Rerender unread count. */
  193. fetchMessage(true, $.createLink('message', 'ajaxGetDropmenuForOld', 'active=all'));
  194. renderMessage();
  195. };
  196. window.markAllRead = function()
  197. {
  198. let $messageItem = $('#messageTabs .message-item.unread');
  199. $messageItem.find('.label-dot.danger').removeClass('danger').addClass('gray');
  200. $messageItem.removeClass('unread');
  201. $('#messageTabs #unread-messages.tab-pane .message-item').addClass('hidden');
  202. $.get($.createLink('message', 'ajaxMarkRead', "id=all"));
  203. renderMessage();
  204. };
  205. window.clearRead = function()
  206. {
  207. let $messageItem = $('#messageTabs .message-item:not(.unread)');
  208. $messageItem.addClass('hidden');
  209. $.get($.createLink('message', 'ajaxDelete', "id=allread"));
  210. renderMessage();
  211. };
  212. window.deleteMessage = function(obj)
  213. {
  214. let $this = $(obj);
  215. if(!$this.hasClass('message-item')) $this = $this.closest('.message-item');
  216. let messageID = $this.data("msgid");
  217. let $messageItem = $('#messageTabs .message-item[data-msgid="' + messageID + '"]');
  218. $messageItem.removeClass('unread');
  219. $messageItem.addClass('hidden');
  220. $.get($.createLink('message', 'ajaxDelete', "id=" + messageID));
  221. /* Rerender unread count. */
  222. renderMessage();
  223. };
  224. window.clickMessage = function(obj)
  225. {
  226. let $obj = $(obj);
  227. let url = $obj.attr('data-url').replace(/\?onlybody=yes/g, '').replace(/\&onlybody=yes/g, '');
  228. markRead(obj);
  229. $('#header #messageBar').trigger('click');
  230. $.apps.openApp(url);
  231. renderMessage();
  232. };
  233. window.renderMessage = function()
  234. {
  235. let $unreadTab = $('#messageTabs #unread-messages.tab-pane');
  236. let unreadCount = $unreadTab.find('.message-item.unread').length;
  237. if(typeof(unreadLangTempate) != 'undefined') $('[href="#unread-messages"] span').html(unreadLangTempate.replace(/%s/, unreadCount));
  238. if(unreadCount == 0)
  239. {
  240. $unreadTab.find('ul').addClass('hidden');
  241. if($unreadTab.find('.nodata').length == 0) $unreadTab.append(noDataHtml);
  242. }
  243. let $allTab = $('#messageTabs #all-messages.tab-pane');
  244. let allCount = $allTab.find('.message-item:not(.hidden)').length;
  245. if(allCount == 0)
  246. {
  247. $allTab.find('ul').addClass('hidden');
  248. if($allTab.find('.nodata').length == 0) $allTab.append(noDataHtml);
  249. }
  250. $('#messageTabs .message-date').each(function()
  251. {
  252. if($(this).find('.message-item:not(.hidden)').length == 0) $(this).addClass('hidden');
  253. });
  254. updateAllDot(showCount);
  255. };
  256. window.updateAllDot = function(showCount)
  257. {
  258. showCount = showCount != '0';
  259. let dotStyle = 'padding: 2px;';
  260. let rightStyle = showCount ? 'right: -10px;' : 'right: -2px;';
  261. if(!showCount) dotStyle += 'width: 5px; height: 5px;';
  262. let $unreadTab = $('#messageTabs #unread-messages.tab-pane');
  263. let unreadCount = $unreadTab.find('.message-item.unread').length;
  264. if(unreadCount < 10 && showCount) rightStyle = 'right: -5px;';
  265. if(unreadCount > 99) unreadCount = '99+';
  266. dotStyle += showCount ? 'top: -3px; aspect-ratio: 0;' : 'top: -2px; aspect-ratio: 1 / 1;';
  267. dotStyle += rightStyle;
  268. let dotHtml = '<span class="label danger label-dot absolute' + (showCount ? ' rounded-sm' : '') + '" style="' + dotStyle + '">' + (showCount ? unreadCount : '') + '</span>';
  269. top.$('#apps .app-container').each(function()
  270. {
  271. let $iframeMessageBar = $(this).find('iframe').contents().find('#messageBar');
  272. if($iframeMessageBar.length > 0)
  273. {
  274. $iframeMessageBar.find('.label-dot.danger').remove();
  275. if(unreadCount) $iframeMessageBar.append(dotHtml);
  276. }
  277. let $oldPage = $(this).find('iframe').contents().find('#oldPage');
  278. if($oldPage.length > 0)
  279. {
  280. $iframeMessageBar = $oldPage.find('iframe').contents().find('#messageBar');
  281. if($iframeMessageBar.length == 0) return;
  282. $iframeMessageBar.find('.label-dot.danger').remove();
  283. if(unreadCount) $iframeMessageBar.append(dotHtml);
  284. }
  285. });
  286. };
  287. window.hideContextMenu = function()
  288. {
  289. if($.zui.ContextMenu.isShow()) $.zui.ContextMenu.hide();
  290. contextmenuEle = null;
  291. };
  292. window.clickContextMenu = function(item)
  293. {
  294. if(contextmenuEle == null) return;
  295. let action = item.value;
  296. let $this = contextmenuEle;
  297. if(action == 'delete') deleteMessage($this);
  298. if(action == 'markunread') markUnread($this);
  299. };
  300. window.toggleSettingDropdown = function(isOpen)
  301. {
  302. if(typeof(isOpen) == 'undefined') isOpen = $('#messageSettingDropdown-toggle').hasClass('open');
  303. $('#messageSettingDropdown-toggle').toggleClass('open', !isOpen);
  304. $('#messageSettingDropdown').toggleClass('show', !isOpen);
  305. };
  306. window.closeSettingDropdown = function(){ toggleSettingDropdown(true); }
  307. window.reloadSettingModal = function(showCount)
  308. {
  309. updateAllDot(showCount);
  310. setTimeout(function()
  311. {
  312. $('#dropdownMessageMenu #messageSettingDropdown').find('form :submit').popover('destroy');
  313. closeSettingDropdown();
  314. }, 1000)
  315. };
  316. let contextmenuEle = null;
  317. $(function()
  318. {
  319. $.ajaxForm('.ajaxForm');
  320. updateAllDot(showCount);
  321. let unreadContextMenu = [{'label': '<?php echo $lang->delete;?>', 'value': 'delete'}];
  322. let readContextMenu = [
  323. {'label': '<?php echo $lang->delete;?>', 'value': 'delete'},
  324. {'label': '<?php echo $lang->message->markUnread;?>', 'value': 'markunread'}
  325. ];
  326. /* Bind contextmenu for message dropdown. */
  327. $(document).on('contextmenu', '*', function(event)
  328. {
  329. hideContextMenu();
  330. let $this = $(this);
  331. if($this.hasClass('message-item') || $this.closest('.message-item').length)
  332. {
  333. event.preventDefault();
  334. event.stopPropagation();
  335. if(!$this.hasClass('message-item')) $this = $this.closest('.message-item');
  336. $.zui.ContextMenu.show($this.hasClass('unread') ? unreadContextMenu : readContextMenu,
  337. {
  338. event: event,
  339. onClickItem: function(item) {clickContextMenu(item);}
  340. }, function() { contextmenuEle = $this; });
  341. return;
  342. }
  343. });
  344. /* Hidden dropdown and contextmenu. */
  345. $(document).on('click', '*', function(event)
  346. {
  347. hideContextMenu();
  348. let $this = $(this);
  349. if($this.hasClass('.contextmenu-menu') || $this.closest('.contextmenu-menu').length)
  350. {
  351. event.stopPropagation();
  352. return;
  353. }
  354. if($this.attr('id') == 'messageDropdown' || $this.closest('#messageDropdown').length)
  355. {
  356. if($this.attr('id') == 'messageDropdown') event.stopPropagation();
  357. if($(event.target).closest('.messageSettingBox').length == 0 && $('#messageSettingDropdown-toggle').hasClass('open')) closeSettingDropdown();
  358. return;
  359. }
  360. $('#messageDropdown #messageBar').removeClass('open');
  361. $('#messageDropdown .messageDropdownBox').removeClass('show');
  362. });
  363. $('#dropdownMessageMenu').on('scroll', function(event){hideContextMenu();});
  364. $(window).on('scroll', function(event){hideContextMenu();});
  365. /* Adjust dropdown height when resize. */
  366. $(window).on('resize', function(event)
  367. {
  368. let maxHeight = $(window).height() - $('#header').height() - 5;
  369. $("#dropdownMessageMenu").css('height', maxHeight).css('max-height', maxHeight)
  370. });
  371. });
  372. </script>