From 24394a41ff7bc8238266986abd9a0e331eb481ad Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 9 May 2024 14:14:48 +0800 Subject: [PATCH] * Finish task #117624. --- module/doc/config.php | 17 ++-- module/doc/control.php | 12 ++- module/doc/css/view.ui.css | 2 +- module/doc/js/uploaddocs.ui.js | 61 ++++++++++++ module/doc/model.php | 7 +- module/doc/ui/createbutton.html.php | 2 +- module/doc/ui/uploaddocs.html.php | 148 ++++++++++++++++++++++++++++ module/doc/ui/view.html.php | 2 + module/doc/zen.php | 4 +- 9 files changed, 237 insertions(+), 18 deletions(-) create mode 100644 module/doc/js/uploaddocs.ui.js create mode 100644 module/doc/ui/uploaddocs.html.php diff --git a/module/doc/config.php b/module/doc/config.php index 0eb497ef69..ca8627a636 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -33,14 +33,15 @@ $config->doc->editor->objectlibs = array('id' => 'comment,lastComment', 'tools' $config->doc->markdown = new stdclass(); $config->doc->markdown->create = array('id' => 'contentMarkdown', 'tools' => 'withchange'); -$config->doc->iconList['html'] = 'rich-text'; -$config->doc->iconList['markdown'] = 'markdown'; -$config->doc->iconList['url'] = 'text-link'; -$config->doc->iconList['text'] = 'wiki-file'; -$config->doc->iconList['template'] = 'wiki-file'; -$config->doc->iconList['word'] = 'word'; -$config->doc->iconList['ppt'] = 'ppt'; -$config->doc->iconList['excel'] = 'excel'; +$config->doc->iconList['html'] = 'rich-text'; +$config->doc->iconList['markdown'] = 'markdown'; +$config->doc->iconList['url'] = 'text-link'; +$config->doc->iconList['text'] = 'wiki-file'; +$config->doc->iconList['template'] = 'wiki-file'; +$config->doc->iconList['word'] = 'word'; +$config->doc->iconList['ppt'] = 'ppt'; +$config->doc->iconList['excel'] = 'excel'; +$config->doc->iconList['attachment'] = 'attachment'; $config->doc->objectIconList['product'] = 'icon-product'; $config->doc->objectIconList['project'] = 'icon-project'; diff --git a/module/doc/control.php b/module/doc/control.php index aacb1a22ac..30c7652d52 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -288,12 +288,20 @@ class doc extends control helper::setcookie('lastDocModule', $moduleID); if(!isset($_POST['lib']) && strpos($_POST['module'], '_') !== false) list($_POST['lib'], $_POST['module']) = explode('_', $_POST['module']); - $docData = form::data($this->config->doc->create)->get(); + if($_POST['type'] == 'attachment' && isset($_FILES['name'])) + { + $this->config->doc->form->create['title']['required'] = false; + $this->config->doc->form->create['title']['skipRequired'] = true; + } + + $docData = form::data($this->config->doc->form->create) + ->setDefault('addedBy', $this->app->user->account) + ->get(); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); if($this->post->uploadFormat == 'combinedDocs') { - $docResult = $this->doc->create($docData, $this->post->labels); + $docResult = $this->doc->create($docData); } else { diff --git a/module/doc/css/view.ui.css b/module/doc/css/view.ui.css index b11eed598f..3cc87a5f72 100644 --- a/module/doc/css/view.ui.css +++ b/module/doc/css/view.ui.css @@ -24,5 +24,5 @@ .w-144 {width: 36rem;} #outlineToggle {display: block; position: absolute; top: 6.5rem; right: 3.5rem; z-index: 100;} -#docPanel .panel-heading > .panel-actions {min-width: 320px;} +#docPanel .panel-heading > .panel-actions.hasEditor {min-width: 320px;} #docPanel .detail-content {max-width: var(--zt-panel-form-max-width); overflow: hidden;} diff --git a/module/doc/js/uploaddocs.ui.js b/module/doc/js/uploaddocs.ui.js new file mode 100644 index 0000000000..f8cb1cc191 --- /dev/null +++ b/module/doc/js/uploaddocs.ui.js @@ -0,0 +1,61 @@ +window.waitDom('.uploadFileBox .file-selector-list', function(){ addFileUploadMutationObserver();}) + +function addFileUploadMutationObserver() +{ + let fileUpload = document.querySelector('.uploadFileBox .file-selector-list'); + observer = new MutationObserver(function(mutationsList, observer) + { + let title = $('.uploadFileBox .file-selector-list .file-selector-item:nth-child(1) .item-title').text(); + let dotIdx = title.lastIndexOf('.'); + if(dotIdx != '-1') title = title.substring(0, dotIdx); + $('.titleBox [name=title]').val(title); + $('.uploadFormatBox').toggleClass('hidden', $('.uploadFileBox .file-selector-list .file-selector-item').length <= 1); + }); + + observer.observe(fileUpload, {childList: true, subtree: true}); +} + +window.loadExecutions = function(e) +{ + const $projectElement = $('.projectBox input[name="project"]'); + const $executionElement = $('.executionBox input[name="execution"]'); + const projectID = $projectElement.val(); + if($executionElement) + { + const executionID = $executionElement.val(); + const link = $.createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&mode=multiple,leaf,noprefix"); + $.getJSON(link, function(data) + { + let $picker = $executionElement.zui('picker'); + $picker.render({items: data.items, disabled: !data.multiple}); + $picker.$.setValue(executionID); + }); + } + + const link = $.createLink('doc', 'ajaxGetModules', 'objectType=project&objectID=' + projectID + '&type=doc'); + $.getJSON(link, function(data) + { + const $picker = $('.moduleBox input[name="module"]').zui('picker'); + $picker.render({items: data}); + $picker.$.setValue(''); + }); +} + +window.openEditURL = function(docID, fileID) +{ + let editUrl = $.createLink('file', 'download', "fileID=" + fileID + "&mouse=left"); + window.open(editUrl); + loadPage($.createLink('doc', 'view', "docID=" + docID)); +} + +window.toggleDocTitle = function() +{ + const uploadFormat = $('.uploadFormatBox input[name=uploadFormat]:checked').val(); + $('.titleBox').toggleClass('hidden', uploadFormat != 'combinedDocs'); +} + + +window.titleChanged = function() +{ + if(observer) observer.disconnect(); +} diff --git a/module/doc/model.php b/module/doc/model.php index a57b7476e9..36d9e63df0 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -857,7 +857,7 @@ class docModel extends model if(empty($doc->lib)) return dao::$errors['lib'] = sprintf($this->lang->error->notempty, $this->lang->doc->lib); $files = $this->loadModel('file')->getUpload(); - if(empty($files)) return dao::$errors['files'] = sprintf($this->lang->error->notempty, $this->lang->doc->uploadFile); + if(isset($files['name'])) return dao::$errors['files'] = sprintf($this->lang->error->notempty, $this->lang->doc->uploadFile); $lib = $this->getLibByID($doc->lib); $doc = $this->loadModel('file')->processImgURL($doc, $this->config->doc->editor->create['id'], (string)$this->post->uid); @@ -936,11 +936,10 @@ class docModel extends model * Create a doc. * * @param object $doc - * @param array|bool $labels * @access public * @return array|bool|string */ - public function create(object $doc, array|bool $labels = false): array|bool|string + public function create(object $doc): array|bool|string { if($doc->acl == 'open') $doc->users = $doc->groups = ''; if(empty($doc->lib) && strpos((string)$doc->module, '_') !== false) list($doc->lib, $doc->module) = explode('_', $doc->module); @@ -972,7 +971,7 @@ class docModel extends model } $files = $this->loadModel('file')->getUpload(); - if($lib->type == 'attachment' && empty($labels)) return dao::$errors['files'] = sprintf($this->lang->error->notempty, $this->lang->doc->uploadFile); + if($doc->type == 'attachment' && isset($files['name'])) return dao::$errors['files'] = sprintf($this->lang->error->notempty, $this->lang->doc->uploadFile); $doc->draft = $docContent->content; $doc->vision = $this->config->vision; diff --git a/module/doc/ui/createbutton.html.php b/module/doc/ui/createbutton.html.php index 88ccc662e0..c911e42745 100644 --- a/module/doc/ui/createbutton.html.php +++ b/module/doc/ui/createbutton.html.php @@ -21,7 +21,7 @@ foreach($lang->doc->createList as $typeKey => $typeName) $docType = zget($config->doc->iconList, $typeKey); $params = "objectType={$createType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type={$typeKey}"; if($typeKey == 'template' and $config->edition == 'max') $params = "objectType={$createType}&objectID={$typeID}&libID={$libID}&moduleID={$moduleID}&type=html&from=template"; - if($typeKey == 'attachment') continue;; + if($typeKey == 'attachment') $method = 'uploadDocs'; $buttonItems[] = array ( diff --git a/module/doc/ui/uploaddocs.html.php b/module/doc/ui/uploaddocs.html.php new file mode 100644 index 0000000000..07fd39471b --- /dev/null +++ b/module/doc/ui/uploaddocs.html.php @@ -0,0 +1,148 @@ + + * @package doc + * @link https://www.zentao.net + */ +namespace zin; + +jsVar('libType', $objectType); +formPanel +( + set::title($lang->doc->uploadDoc), + set::submitBtnText($lang->save), + $objectType == 'project' ? formRow + ( + formGroup + ( + setClass('projectBox'), + set::label($lang->doc->project), + set::name('project'), + set::items($objects), + set::value($objectID), + on::change('loadExecutions'), + set::required(true) + ), + $app->tab == 'doc' ? formGroup + ( + set::width('1/2'), + setClass('executionBox'), + set::label($lang->doc->execution), + set::name('execution'), + set::items($executions), + set::placeholder($lang->doc->placeholder->execution), + on::change('loadObjectModules') + ) : null + ) : null, + $objectType == 'execution' ? formGroup + ( + set::label($lang->doc->execution), + set::name('execution'), + set::items($objects), + set::value($objectID), + on::change('loadObjectModules'), + set::required(true) + ) : null, + $objectType == 'product' ? formGroup + ( + set::label($lang->doc->product), + set::name('product'), + set::items($objects), + set::value($objectID), + on::change('loadObjectModules'), + set::required(true) + ) : null, + formGroup + ( + setClass('moduleBox'), + set::label($lang->doc->libAndModule), + set::name('module'), + set::items($moduleOptionMenu), + set::value($moduleID), + set::required(true) + ), + formGroup + ( + setClass('uploadFileBox'), + set::label($lang->doc->uploadFile), + fileSelector(), + set::required(true) + ), + formGroup + ( + setClass('uploadFormatBox'), + set::hidden(true), + set::label($lang->doc->uploadFormat), + radioList + ( + set::name('uploadFormat'), + set::items($lang->doc->uploadFormatList), + set::value('separateDocs'), + set::inline(true), + on::change('toggleDocTitle') + ) + ), + formGroup + ( + setClass('titleBox'), + set::hidden(true), + set::label($lang->doc->title), + set::name('title'), + set::required(true), + on::input('titleChanged') + ), + formRow + ( + setID('aclBox'), + formGroup + ( + set::label($lang->doclib->control), + radioList + ( + set::name('acl'), + set::items($lang->doc->aclList), + set::value($objectType == 'mine' ? 'private' : 'open'), + on::change("toggleAcl('doc')") + ) + ) + ), + formRow + ( + setID('whiteListBox'), + setClass('hidden'), + formGroup + ( + set::label($lang->doc->whiteList), + div + ( + setClass('w-full check-list'), + div + ( + setClass('w-full'), + inputGroup + ( + $lang->doclib->group, + picker + ( + set::name('groups[]'), + set::items($groups), + set::multiple(true) + ) + ) + ), + div + ( + setClass('w-full'), + userPicker(set::label($lang->doclib->user), set::items($users)) + ) + ) + ) + ), + formHidden('status', 'normal'), + formHidden('type', $docType), + formHidden('contentType', 'html') +); diff --git a/module/doc/ui/view.html.php b/module/doc/ui/view.html.php index d827c4dfaa..dcbefd4cf1 100644 --- a/module/doc/ui/view.html.php +++ b/module/doc/ui/view.html.php @@ -152,6 +152,7 @@ $contentDom = div div ( setClass('panel-actions flex'), + $editorGroup ? setClass('hasEditor') : null, div ( setClass('toolbar'), @@ -166,6 +167,7 @@ $contentDom = div common::hasPriv('doc', 'edit') && !$doc->deleted ? btn ( set::url(createLink('doc', 'edit', "docID=$doc->id")), + $doc->type != 'text' ? setData('toggle', 'modal') : null, setClass('btn ghost'), icon('edit') ) : null, diff --git a/module/doc/zen.php b/module/doc/zen.php index cc7aa1f4d4..b2f5d609f0 100644 --- a/module/doc/zen.php +++ b/module/doc/zen.php @@ -453,11 +453,11 @@ class docZen extends doc * 在上传文件后的返回。 * Return after upload files. * - * @param array $docResult + * @param array|string $docResult * @access protected * @return bool|int */ - protected function responseAfterUploadDocs(array $docResult): bool|int + protected function responseAfterUploadDocs(array|string $docResult): bool|int { if(!$docResult || dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));