From 8b6197791cd697bdee184c82489c835dddb322e9 Mon Sep 17 00:00:00 2001 From: sunguangming Date: Thu, 27 Jul 2023 14:11:01 +0800 Subject: [PATCH] * Finish task #98356. --- module/doc/css/view.ui.css | 12 ++ module/doc/js/view.ui.js | 102 ++++++++++++++++ module/doc/ui/view.html.php | 226 ++++++++++++++++++++++++++++++++++++ 3 files changed, 340 insertions(+) create mode 100644 module/doc/css/view.ui.css create mode 100644 module/doc/js/view.ui.js create mode 100644 module/doc/ui/view.html.php diff --git a/module/doc/css/view.ui.css b/module/doc/css/view.ui.css new file mode 100644 index 0000000000..d93df9d96d --- /dev/null +++ b/module/doc/css/view.ui.css @@ -0,0 +1,12 @@ +.panel-heading .title {font-size: 18px; font-weight: 600} +.panel-heading { justify-content: space-between; } +.panel-actions { margin-left: auto; } +#content .user-time {margin-right: 4px; color: #838a9d} +#content .user-time .icon {margin-right: 4px} + +.scrollbar-hover { overflow-y: scroll; } +#mainContent .panel+.panel {flex: none} +#history{ position: relative;} +#history > #closeBtn { position: absolute; right: 10px; top: 10px;} + +#content {height: calc(100vh - 300px); overflow-y: auto} diff --git a/module/doc/js/view.ui.js b/module/doc/js/view.ui.js new file mode 100644 index 0000000000..e6f7888334 --- /dev/null +++ b/module/doc/js/view.ui.js @@ -0,0 +1,102 @@ +/** + * Display the document in full screen. + * + * @access public + * @return void + */ +window.fullScreen = function() +{ + var element = document.getElementById('content'); + var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen; + if(requestMethod) + { + var afterEnterFullscreen = function() + { + $('#content').addClass('scrollbar-hover'); + $('#content').css('background', '#fff'); + $.cookie.set('isFullScreen', 1); + }; + + var whenFailEnterFullscreen = function(error) + { + $.cookie.set('isFullScreen', 0); + }; + + try + { + var result = requestMethod.call(element); + if(result && (typeof result.then === 'function' || result instanceof window.Promise)) + { + result.then(afterEnterFullscreen).catch(whenFailEnterFullscreen); + } + else + { + afterEnterFullscreen(); + } + } + catch (error) + { + whenFailEnterFullscreen(error); + } + } +} + +/** + * Exit full screen. + * + * @access public + * @return void + */ +function exitFullScreen() +{ + $('#content').removeClass('scrollbar-hover'); + $.cookie.set('isFullScreen', 0); +} + +document.addEventListener('fullscreenchange', function (e) +{ + if(!document.fullscreenElement) exitFullScreen(); +}); + +document.addEventListener('webkitfullscreenchange', function (e) +{ + if(!document.webkitFullscreenElement) exitFullScreen(); +}); + +document.addEventListener('mozfullscreenchange', function (e) +{ + if(!document.mozFullScreenElement) exitFullScreen(); +}); + +document.addEventListener('msfullscreenChange', function (e) +{ + if(!document.msfullscreenElement) exitFullScreen(); +}); + +$(function() +{ + if($.cookie.get('isFullScreen') == 1) fullScreen(); + + /* Update doc content silently on switch doc version, story #40503 */ + $('.panel').on('click', '#hisTrigger', function() + { + var $history = $('#history'); + var $icon = $(this); + if($history.hasClass('hidden')) + { + $history.removeClass('hidden'); + $icon.addClass('text-primary'); + } + else + { + $history.addClass('hidden'); + $icon.removeClass('text-primary'); + } + }).on('click', '#closeBtn', function() + { + $('#history').addClass('hidden'); + $('#hisTrigger').removeClass('text-primary'); + }); + + $('#history').append(''); +}); diff --git a/module/doc/ui/view.html.php b/module/doc/ui/view.html.php new file mode 100644 index 0000000000..adf2d1cb18 --- /dev/null +++ b/module/doc/ui/view.html.php @@ -0,0 +1,226 @@ + + * @package doc + * @link https://www.zentao.net + */ +namespace zin; + +featureBar +( + li(backBtn(setClass('ghost'), set::icon('back'), $lang->goback)), +); + +if($libID && common::hasPriv('doc', 'create')) include 'createbutton.html.php'; +include './left.html.php'; + +toolbar +( + $canExport ? item(set(array + ( + 'id' => $exportMethod, + 'icon' => 'export', + 'class' => 'ghost export', + 'text' => $lang->export, + 'url' => $createLink('doc', $exportMethod, "libID={$libID}&moduleID={$moduleID}"), + 'data-toggle' => 'modal' + ))) : null, + common::hasPriv('doc', 'createLib') ? item(set(array + ( + 'icon' => 'plus', + 'class' => 'btn secondary', + 'text' => $lang->doc->createLib, + 'url' => createLink('doc', 'createLib', "type={$type}&objectID={$objectID}"), + 'data-toggle' => 'modal' + ))) : null, + $libID && common::hasPriv('doc', 'create') ? $createButton : null +); + +$versionList = array(); +for($itemVersion = $doc->version; $itemVersion > 0; $itemVersion--) +{ + $versionList[] = array('text' => "V$itemVersion", 'url' => createLink('doc', 'view', "docID={$docID}&version={$itemVersion}")); +} + +$star = strpos($doc->collector, ',' . $app->user->account . ',') !== false ? 'star' : 'star-empty'; +$collectLink = $this->createLink('doc', 'collect', "objectID=$doc->id&objectType=doc"); +$starBtn = "" . html::image("static/svg/{$star}.svg", "class='$star'") . ''; + +/* 导入资产库的按钮. */ +if($config->vision == 'rnd' and $config->edition == 'max' and $app->tab == 'project') +{ + $canImportToPracticeLib = (common::hasPriv('doc', 'importToPracticeLib') and helper::hasFeature('practicelib')); + $canImportToComponentLib = (common::hasPriv('doc', 'importToComponentLib') and helper::hasFeature('componentlib')); + + if($canImportToPracticeLib) $items[] = array('text' => $lang->doc->importToPracticeLib, 'url' => '#importToPracticeLib', 'data-toggle' => 'modal'); + if($canImportToComponentLib) $items[] = array('text' => $lang->doc->importToComponentLib, 'url' => '#importToComponentLib', 'data-toggle' => 'modal'); + + $importLibBtn = $items ? dropdown + ( + btn + ( + setClass('ghost btn square btn-default'), + icon('diamond') + ), + set::items($items) + ) : null; +} + +$createInfo = $doc->status == 'draft' ? zget($users, $doc->addedBy) . " {$lang->colon} " . substr($doc->addedDate, 0, 10) . (common::checkNotCN() ? ' ' : '') . $lang->doc->createAB : zget($users, $doc->releasedBy) . " {$lang->colon} " . substr($doc->releasedDate, 0, 10) . (common::checkNotCN() ? ' ' : '') . $lang->doc->release; + +$keywordsLabel = array(); +if($doc->keywords) +{ + foreach($doc->keywords as $keywords) + { + if($keywords) + { + $keywordsLabel[] = span + ( + setClass('label secondary-outline'), + $keywords + ); + } + } +} + +/* Build editor group. */ +$editorGroup = ''; +if(!empty($editors)) +{ + $space = common::checkNotCN() ? ' ' : ''; + $firstEditor = current($editors); + $editorInfo = zget($users, $firstEditor->account) . ' ' . substr($firstEditor->date, 0, 10) . $space . $lang->doc->update; + + array_shift($editors); + + $items = array(); + foreach($editors as $editor) + { + $info = zget($users, $editor->account) . ' ' . substr($editor->date, 0, 10) . $space . $lang->doc->update; + $items[] = array('text' => $info); + } + + $editorGroup = dropdown + ( + btn + ( + setClass('ghost btn square btn-default'), + $editorInfo + ), + set::items($items) + ); +} + +panel +( + div + ( + setClass('panel-heading'), + div + ( + setClass('title'), + $doc->title + ), + dropdown + ( + btn + ( + setClass('ghost btn square btn-default'), + 'V' . ($version ? $version : $doc->version) + ), + set::items($versionList) + ), + div + ( + setClass('panel-actions flex'), + div + ( + setClass('toolbar'), + btn + ( + set::url('javascript:fullScreen()'), + setClass('btn ghost'), + icon('fullscreen'), + ), + common::hasPriv('doc', 'collect') ? html($starBtn) : null, + ($config->vision == 'rnd' and $config->edition == 'max' and $app->tab == 'project') ? $importLibBtn : null, + (!$isRelease && common::hasPriv('doc', 'edit')) ? btn + ( + set::url(createLink('doc', 'edit', "docID=$doc->id")), + setClass('btn ghost'), + icon('edit'), + ) : null, + (!$isRelease && common::hasPriv('doc', 'delete')) ? btn + ( + set::url(createLink('doc', 'delete', "docID=$doc->id")), + setClass('btn ghost ajax-submit'), + set('data-confirm', $lang->doc->confirmDelete), + icon('trash'), + ) : null, + btn + ( + set::id('hisTrigger'), + set::url('###)'), + setClass('btn ghost'), + icon('clock'), + ), + ), + div + ( + set::id('editorBox'), + setClass('flex'), + $editorGroup + ) + ) + ), + div + ( + set::Class('panel-body'), + set::id('content'), + div + ( + setClass('info'), + span + ( + setClass('user-time'), + icon('contacts'), + $createInfo, + ), + span + ( + setClass('user-time'), + icon('star'), + $doc->collects ? $doc->collects : 0, + ), + span + ( + setClass('user-time'), + icon('eye'), + $doc->views, + ), + $keywordsLabel ? span + ( + setClass('keywords'), + $keywordsLabel + ) : null, + ), + html($doc->content) + ), + h::hr(), + fileList + ( + set::files($doc->files) + ) +); + +panel +( + set::id('history'), + setClass('hidden'), + history() +);