const savingDocData = {}; let docBasicModal = {}; let currentUser = null; /** * 获取文档界面上的表格初始化选项。 * Get the table initialization options on the doc UI. * * @param {object} options * @param {object} info * @returns {object} */ function getTableOptions(options, info) { const lang = getDocAppLang(); options.data.sort((a, b) => a.addedDate > b.addedDate ? -1 : 1); templateCols = []; templateCols.push({...options.cols.find(col => col.name === 'rawID'), type: 'id'}); let title = options.cols.find(col => col.name == 'title'); let addedBy = options.cols.find(col => col.name == 'addedBy'); let addedDate = options.cols.find(col => col.name == 'addedDate'); let editedBy = options.cols.find(col => col.name == 'editedBy'); let editedDate = options.cols.find(col => col.name == 'editedDate'); let actionsCol = options.cols.find(col => col.name == 'actions'); let typeCol = {name: 'moduleName', title: lang.tableCols.type, type: 'string', sort: true}; let viewsCol = {name: 'views', title: lang.tableCols.views, type: 'number', width: '80px', sort: true}; let descCol = {name: 'templateDesc', title: lang.tableCols.desc, type: 'desc', sort: true} title.title = lang.tableCols.title; addedBy.title = lang.tableCols.addedBy; addedDate.title = lang.tableCols.addedDate; editedBy.title = lang.tableCols.editedBy; editedDate.title = lang.tableCols.editedDate; actionsCol.title = lang.tableCols.actions; templateCols.push(title); templateCols.push(typeCol); templateCols.push(addedBy); templateCols.push(addedDate); templateCols.push(editedBy); templateCols.push(editedDate); templateCols.push(viewsCol); templateCols.push(descCol); templateCols.push(actionsCol); options.cols = templateCols; options.cols.forEach(col => { if(col.name === 'actions' && col.actionsMap) { col.actions = col.actions.filter(action => (action !== 'move' && docAppHasPriv(action))); delete col.actionsMap.move; const privMap = {edit: docAppHasPriv('edit'), delete: docAppHasPriv('delete')}; const actionHints = {edit: lang.editTemplate, delete: lang.deleteTemplate}; $.each(col.actionsMap, (key, value) => { if(typeof actionHints[key] === 'string') value.hint = actionHints[key]; value.disabled = !privMap[key]; }); } }); options.checkable = false; options.footer = options.footer.filter(f => f !== 'checkbox'); options.footer = options.footer.filter(f => f !== 'checkedInfo'); return options; } function mergeDocFormData(doc, formData) { if(!doc || !formData) return; const keys = new Set(formData.keys()); for(const key of keys) { const values = formData.getAll(key); if(!values.length) continue; if(key === 'module' || key === 'lib') doc[key] = +values[0]; else doc[key] = values.length > 1 ? values : values[0]; } return doc; } function showDocBasicModal(parentID, docID, isDraft, modalType = 'doc') { const docApp = getDocApp(); const spaceID = docApp.spaceID; const spaceType = docApp.spaceType; const libID = docApp.libID; const moduleID = docApp.moduleID; const url = $.createLink('doc', 'setDocBasic', `objectType=template&objectID=${spaceID}&libID=${libID}&moduleID=${moduleID}&parentID=${parentID || 0}&docID=${docID || 0}&isDraft=${isDraft ? 'yes' : 'no'}&modalType=${modalType}`); if(docBasicModal.doc === docID && docBasicModal.current) { docBasicModal.current.show(); } else { if(docBasicModal.current) docBasicModal.current.destroy(); docBasicModal.doc = docID; zui.Modal.open( { key : `${config.currentModule}-${config.currentMethod}-${spaceType}-${docID}`, ref : docBasicModal, url : url, destroyOnHide: !docID, cache : true, request: { error: error => { if(docBasicModal.current) docBasicModal.current.hide(); showSaveFailedAlert(error); } }, onHidden: () => { if(!docBasicModal.keepOnHide && docBasicModal.current) docBasicModal.current.destroy(); }, $onDestroy: () => { if(docBasicModal.current) docBasicModal = {}; } }); } return new Promise((resolve) => {window.docBasicModalResolver = resolve;}); } window.beforeSetDocBasicInfo = function(_, form) { docBasicModal.keepOnHide = true; if (window.docBasicModalResolver) window.docBasicModalResolver(new FormData(form)); zui.Modal.query('#setDocBasicForm').hide(); return false; }; function showDocSettingModal(_, args) { const docApp = getDocApp(); const doc = docApp.doc; const docID = args[0] || doc.id; const docType = args[1] || doc.contentType; const saveEdited = args[2] || 0; showDocBasicModal(doc.data.parent, docID).then(formData => { savingDocData[docID] = formData; if(saveEdited == 1) { const docData = { content : doc.data.content, status : doc.data.status, contentType: doc.data.contentType, type : doc.data.type, lib : doc.data.lib, module : doc.data.module, title : doc.data.title, keywords : doc.data.keywords, acl : doc.data.acl, space : doc.data.space, uid : doc.data.uid, }; mergeDocFormData(docData, formData); } }); } /** * 向服务器提交新文档。 * Submit new doc to server. * * @param {object} doc * @param {number} spaceID * @param {number} libID * @param {number} moduleID * @param {FormData} formData * @returns */ function submitNewDoc(doc, spaceID, libID, moduleID, formData, afterCreate) { const docApp = getDocApp(); if(docApp.isSavingDoc) return; docApp.isSavingDoc = true; $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').attr('disabled', true); const spaceType = docApp.signals.spaceType.value; const module = docApp.treeMap.modules.get(formData && moduleID === 0 ? parseInt(formData.get('module')) : moduleID); const url = $.createLink('doc', 'createTemplate', `libID=${libID}&moduleID=${moduleID}`); const docData = { rawContent : doc.content, content : doc.html, status : doc.status || 'normal', contentType : doc.contentType, type : doc.type || 'text', lib : libID, module : moduleID, title : doc.title, keywords : doc.keywords, templateDesc : doc.templateDesc, acl : 'private', space : spaceType, project : 0, templateType : module && module.data ? module.data.short : '', uid : (doc.uid || `doc${doc.id}`), parent : doc.parent }; if(formData) mergeDocFormData(docData, formData); docApp.props.fetcher = $.createLink('doc', 'ajaxGetSpaceData', `type=template&spaceID=${spaceID}&picks={picks}&libID=${libID}`); const getErrorMessage = (res) => { if(typeof res.message === 'string') return res.message; if(typeof res.message === 'object' && res.message && Object.values(res.message).length) { for(const x of Object.values(res.message)) { if(typeof x === 'string') return x; if(Array.isArray(x) && x.length) return x[0]; } } if(typeof data.error === 'string') return data.error; return getLang('errorOccurred'); }; return new Promise((resolve, reject) => { $.post(url, docData, (res) => { try { const data = JSON.parse(res); if(!checkResponse(data)) return; if(typeof data !== 'object' || data.result === 'fail') { throw new Error(getErrorMessage(data)); } const newDoc = $.extend(doc, {id: data.id}, docData, data.doc, {status: doc.status || data.status}); if (!newDoc.space.includes('.')) { newDoc.space = `${spaceType}.${docData[spaceType]}`; } resolve(newDoc); if(afterCreate) { docApp.load(null, null, null, {noLoading: true, picks: 'doc'}).then(() => { afterCreate(newDoc); }); } } catch (error) { showSaveFailedAlert(error); reject(error); } }).fail(error => { resolve(false); showSaveFailedAlert(error); }).complete(() => { docApp.isSavingDoc = false; $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').removeAttr('disabled'); }); }); } /** * 向服务器提交编辑文档内容。 * Submit edit doc to server. * * @param {FormData} formData * @access public * @return void */ function submitEditDoc(formData) { const docApp = getDocApp(); const doc = docApp.doc.data; const url = $.createLink('doc', 'editTemplate', `templateID=${doc.id}`); if(formData) mergeDocFormData(doc, formData); return new Promise((resolve) => { $.post(url, doc, (res) => { try { const data = JSON.parse(res); if(!checkResponse(data)) return; if(typeof data !== 'object' || data.result === 'fail') { let message = data.message || data.error || getLang('errorOccurred'); if(typeof message === 'object') message = Object.values(message).map(x => Array.isArray(x) ? x.join('\n') : x).join('\n'); throw new Error(message); } resolve(doc); } catch (error) { resolve(false); showSaveFailedAlert(error); if(!error.message) return; } }).fail(error => { resolve(false); showSaveFailedAlert(error); }).complete(() => { docApp.load(null, null, null, {noLoading: true, picks: 'doc'}); }); }); } /** * 处理创建文档的操作请求,向服务器发送请求并返回创建的文档对象。 * Handle the create doc operation request, send a request to the server and return the created doc object. */ function handleCreateDoc(doc, spaceID, libID, moduleID) { return showDocBasicModal(0, 0, doc.status === 'draft').then((formData) => { moduleID = parseInt(formData.get('module')); return submitNewDoc(doc, spaceID, libID, moduleID, formData); }); } /** * 处理保存文档的操作请求,向服务器发送请求并返回保存的文档对象。 * Handle the save doc operation request, send a request to the server and return the saved doc object. */ function handleSaveDoc(doc) { const docApp = getDocApp(); const spaceType = docApp.signals.spaceType.value; const libID = docApp.signals.libID.value; const moduleID = docApp.signals.moduleID.value; const url = $.createLink('doc', 'editTemplate', `docID=${doc.id}`); const docData = { rawContent : doc.content, status : doc.status || 'normal', contentType : doc.contentType, type : 'text', lib : libID, module : moduleID, title : doc.title, keywords : doc.keywords, templateDesc : doc.templateDesc, acl : doc.acl, content : doc.html, isDeliverable : doc.isDeliverable || '0', space : spaceType, uid : (doc.uid || `doc${doc.id}`), }; const docAppData = docApp.doc.data; if (doc.id === docAppData.id) docData.mailto = docAppData.mailto; if(savingDocData[doc.id]) { mergeDocFormData(docData, savingDocData[doc.id]); delete savingDocData[doc.id]; } return new Promise((resolve) => { $.post(url, docData, (res) => { try { const data = JSON.parse(res); if(!checkResponse(data)) return; if(typeof data !== 'object' || data.result === 'fail') { let message = data.message || data.error || getLang('errorOccurred'); if(typeof message === 'object') message = Object.values(message).map(x => Array.isArray(x) ? x.join('\n') : x).join('\n'); throw new Error(message); } doc = $.extend({}, doc, docData, data.doc); const libID = +doc.lib; const lib = docApp.getLib(libID); if(!lib) { resolve(false); return loadPage($.createLink('doc', 'view', `docID=${doc.id}`)); } delete doc.title; delete doc.keywords; delete doc.content; resolve(doc); } catch (error) { resolve(false); if(!error.message) return; zui.Modal.alert(error.message); } }).fail(error => { resolve(false); showSaveFailedAlert(error); }).complete(() => { docApp.isSavingDoc = false; docApp.props.fetcher = $.createLink('doc', 'ajaxGetSpaceData', `type=template&spaceID=${docAppData.space}&picks={picks}&libID=${docAppData.lib}`); $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').removeAttr('disabled'); const {id, acl, users, addedBy} = doc; if(acl == 'private' && addedBy !== currentUser) { if(docApp.hasEditingDoc) { docApp.cancelEditDoc().then(() => { docApp.delete('doc', id); }); } else { docApp.delete('doc', id); } } docApp.load(null, null, null, {noLoading: false, picks: 'doc'}); }); }); } const customRenders = { home: function() { const homeViewUrl = $.createLink('doc', 'browseTemplate', `libID=0&filterType=all&docID=0&orderBy=&recPerPage=20&pageID=1&mode=home`); return {fetcher: homeViewUrl, clearBeforeLoad: false, className: 'doc-template-home h-full', class: 'h-full col',htmlRender: (element, props) => $(element).morphInner(`