browsetemplate.ui.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. const savingDocData = {};
  2. let docBasicModal = {};
  3. let currentUser = null;
  4. /**
  5. * 获取文档界面上的表格初始化选项。
  6. * Get the table initialization options on the doc UI.
  7. *
  8. * @param {object} options
  9. * @param {object} info
  10. * @returns {object}
  11. */
  12. function getTableOptions(options, info)
  13. {
  14. const lang = getDocAppLang();
  15. options.data.sort((a, b) => a.addedDate > b.addedDate ? -1 : 1);
  16. templateCols = [];
  17. templateCols.push({...options.cols.find(col => col.name === 'rawID'), type: 'id'});
  18. let title = options.cols.find(col => col.name == 'title');
  19. let addedBy = options.cols.find(col => col.name == 'addedBy');
  20. let addedDate = options.cols.find(col => col.name == 'addedDate');
  21. let editedBy = options.cols.find(col => col.name == 'editedBy');
  22. let editedDate = options.cols.find(col => col.name == 'editedDate');
  23. let actionsCol = options.cols.find(col => col.name == 'actions');
  24. let typeCol = {name: 'moduleName', title: lang.tableCols.type, type: 'string', sort: true};
  25. let viewsCol = {name: 'views', title: lang.tableCols.views, type: 'number', width: '80px', sort: true};
  26. let descCol = {name: 'templateDesc', title: lang.tableCols.desc, type: 'desc', sort: true}
  27. title.title = lang.tableCols.title;
  28. addedBy.title = lang.tableCols.addedBy;
  29. addedDate.title = lang.tableCols.addedDate;
  30. editedBy.title = lang.tableCols.editedBy;
  31. editedDate.title = lang.tableCols.editedDate;
  32. actionsCol.title = lang.tableCols.actions;
  33. templateCols.push(title);
  34. templateCols.push(typeCol);
  35. templateCols.push(addedBy);
  36. templateCols.push(addedDate);
  37. templateCols.push(editedBy);
  38. templateCols.push(editedDate);
  39. templateCols.push(viewsCol);
  40. templateCols.push(descCol);
  41. templateCols.push(actionsCol);
  42. options.cols = templateCols;
  43. options.cols.forEach(col =>
  44. {
  45. if(col.name === 'actions' && col.actionsMap)
  46. {
  47. col.actions = col.actions.filter(action => (action !== 'move' && docAppHasPriv(action)));
  48. delete col.actionsMap.move;
  49. const privMap = {edit: docAppHasPriv('edit'), delete: docAppHasPriv('delete')};
  50. const actionHints = {edit: lang.editTemplate, delete: lang.deleteTemplate};
  51. $.each(col.actionsMap, (key, value) =>
  52. {
  53. if(typeof actionHints[key] === 'string') value.hint = actionHints[key];
  54. value.disabled = !privMap[key];
  55. });
  56. }
  57. });
  58. options.checkable = false;
  59. options.footer = options.footer.filter(f => f !== 'checkbox');
  60. options.footer = options.footer.filter(f => f !== 'checkedInfo');
  61. return options;
  62. }
  63. function mergeDocFormData(doc, formData)
  64. {
  65. if(!doc || !formData) return;
  66. const keys = new Set(formData.keys());
  67. for(const key of keys)
  68. {
  69. const values = formData.getAll(key);
  70. if(!values.length) continue;
  71. if(key === 'module' || key === 'lib') doc[key] = +values[0];
  72. else doc[key] = values.length > 1 ? values : values[0];
  73. }
  74. return doc;
  75. }
  76. function showDocBasicModal(parentID, docID, isDraft, modalType = 'doc')
  77. {
  78. const docApp = getDocApp();
  79. const spaceID = docApp.spaceID;
  80. const spaceType = docApp.spaceType;
  81. const libID = docApp.libID;
  82. const moduleID = docApp.moduleID;
  83. 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}`);
  84. if(docBasicModal.doc === docID && docBasicModal.current)
  85. {
  86. docBasicModal.current.show();
  87. }
  88. else
  89. {
  90. if(docBasicModal.current) docBasicModal.current.destroy();
  91. docBasicModal.doc = docID;
  92. zui.Modal.open(
  93. {
  94. key : `${config.currentModule}-${config.currentMethod}-${spaceType}-${docID}`,
  95. ref : docBasicModal,
  96. url : url,
  97. destroyOnHide: !docID,
  98. cache : true,
  99. request: {
  100. error: error => {
  101. if(docBasicModal.current) docBasicModal.current.hide();
  102. showSaveFailedAlert(error);
  103. }
  104. },
  105. onHidden: () => {
  106. if(!docBasicModal.keepOnHide && docBasicModal.current) docBasicModal.current.destroy();
  107. },
  108. $onDestroy: () => {
  109. if(docBasicModal.current) docBasicModal = {};
  110. }
  111. });
  112. }
  113. return new Promise((resolve) => {window.docBasicModalResolver = resolve;});
  114. }
  115. window.beforeSetDocBasicInfo = function(_, form)
  116. {
  117. docBasicModal.keepOnHide = true;
  118. if (window.docBasicModalResolver) window.docBasicModalResolver(new FormData(form));
  119. zui.Modal.query('#setDocBasicForm').hide();
  120. return false;
  121. };
  122. function showDocSettingModal(_, args)
  123. {
  124. const docApp = getDocApp();
  125. const doc = docApp.doc;
  126. const docID = args[0] || doc.id;
  127. const docType = args[1] || doc.contentType;
  128. const saveEdited = args[2] || 0;
  129. showDocBasicModal(doc.data.parent, docID).then(formData => {
  130. savingDocData[docID] = formData;
  131. if(saveEdited == 1)
  132. {
  133. const docData = {
  134. content : doc.data.content,
  135. status : doc.data.status,
  136. contentType: doc.data.contentType,
  137. type : doc.data.type,
  138. lib : doc.data.lib,
  139. module : doc.data.module,
  140. title : doc.data.title,
  141. keywords : doc.data.keywords,
  142. acl : doc.data.acl,
  143. space : doc.data.space,
  144. uid : doc.data.uid,
  145. };
  146. mergeDocFormData(docData, formData);
  147. }
  148. });
  149. }
  150. /**
  151. * 向服务器提交新文档。
  152. * Submit new doc to server.
  153. *
  154. * @param {object} doc
  155. * @param {number} spaceID
  156. * @param {number} libID
  157. * @param {number} moduleID
  158. * @param {FormData} formData
  159. * @returns
  160. */
  161. function submitNewDoc(doc, spaceID, libID, moduleID, formData, afterCreate)
  162. {
  163. const docApp = getDocApp();
  164. if(docApp.isSavingDoc) return;
  165. docApp.isSavingDoc = true;
  166. $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').attr('disabled', true);
  167. const spaceType = docApp.signals.spaceType.value;
  168. const module = docApp.treeMap.modules.get(formData && moduleID === 0 ? parseInt(formData.get('module')) : moduleID);
  169. const url = $.createLink('doc', 'createTemplate', `libID=${libID}&moduleID=${moduleID}`);
  170. const docData =
  171. {
  172. rawContent : doc.content,
  173. content : doc.html,
  174. status : doc.status || 'normal',
  175. contentType : doc.contentType,
  176. type : doc.type || 'text',
  177. lib : libID,
  178. module : moduleID,
  179. title : doc.title,
  180. keywords : doc.keywords,
  181. templateDesc : doc.templateDesc,
  182. acl : 'private',
  183. space : spaceType,
  184. project : 0,
  185. templateType : module && module.data ? module.data.short : '',
  186. uid : (doc.uid || `doc${doc.id}`),
  187. parent : doc.parent
  188. };
  189. if(formData) mergeDocFormData(docData, formData);
  190. docApp.props.fetcher = $.createLink('doc', 'ajaxGetSpaceData', `type=template&spaceID=${spaceID}&picks={picks}&libID=${libID}`);
  191. const getErrorMessage = (res) => {
  192. if(typeof res.message === 'string') return res.message;
  193. if(typeof res.message === 'object' && res.message && Object.values(res.message).length)
  194. {
  195. for(const x of Object.values(res.message))
  196. {
  197. if(typeof x === 'string') return x;
  198. if(Array.isArray(x) && x.length) return x[0];
  199. }
  200. }
  201. if(typeof data.error === 'string') return data.error;
  202. return getLang('errorOccurred');
  203. };
  204. return new Promise((resolve, reject) =>
  205. {
  206. $.post(url, docData, (res) =>
  207. {
  208. try
  209. {
  210. const data = JSON.parse(res);
  211. if(!checkResponse(data)) return;
  212. if(typeof data !== 'object' || data.result === 'fail')
  213. {
  214. throw new Error(getErrorMessage(data));
  215. }
  216. const newDoc = $.extend(doc, {id: data.id}, docData, data.doc, {status: doc.status || data.status});
  217. if (!newDoc.space.includes('.')) {
  218. newDoc.space = `${spaceType}.${docData[spaceType]}`;
  219. }
  220. resolve(newDoc);
  221. if(afterCreate)
  222. {
  223. docApp.load(null, null, null, {noLoading: true, picks: 'doc'}).then(() => {
  224. afterCreate(newDoc);
  225. });
  226. }
  227. }
  228. catch (error)
  229. {
  230. showSaveFailedAlert(error);
  231. reject(error);
  232. }
  233. }).fail(error => {
  234. resolve(false);
  235. showSaveFailedAlert(error);
  236. }).complete(() => {
  237. docApp.isSavingDoc = false;
  238. $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').removeAttr('disabled');
  239. });
  240. });
  241. }
  242. /**
  243. * 向服务器提交编辑文档内容。
  244. * Submit edit doc to server.
  245. *
  246. * @param {FormData} formData
  247. * @access public
  248. * @return void
  249. */
  250. function submitEditDoc(formData)
  251. {
  252. const docApp = getDocApp();
  253. const doc = docApp.doc.data;
  254. const url = $.createLink('doc', 'editTemplate', `templateID=${doc.id}`);
  255. if(formData) mergeDocFormData(doc, formData);
  256. return new Promise((resolve) => {
  257. $.post(url, doc, (res) =>
  258. {
  259. try
  260. {
  261. const data = JSON.parse(res);
  262. if(!checkResponse(data)) return;
  263. if(typeof data !== 'object' || data.result === 'fail')
  264. {
  265. let message = data.message || data.error || getLang('errorOccurred');
  266. if(typeof message === 'object') message = Object.values(message).map(x => Array.isArray(x) ? x.join('\n') : x).join('\n');
  267. throw new Error(message);
  268. }
  269. resolve(doc);
  270. }
  271. catch (error)
  272. {
  273. resolve(false);
  274. showSaveFailedAlert(error);
  275. if(!error.message) return;
  276. }
  277. }).fail(error => {
  278. resolve(false);
  279. showSaveFailedAlert(error);
  280. }).complete(() => {
  281. docApp.load(null, null, null, {noLoading: true, picks: 'doc'});
  282. });
  283. });
  284. }
  285. /**
  286. * 处理创建文档的操作请求,向服务器发送请求并返回创建的文档对象。
  287. * Handle the create doc operation request, send a request to the server and return the created doc object.
  288. */
  289. function handleCreateDoc(doc, spaceID, libID, moduleID)
  290. {
  291. return showDocBasicModal(0, 0, doc.status === 'draft').then((formData) => {
  292. moduleID = parseInt(formData.get('module'));
  293. return submitNewDoc(doc, spaceID, libID, moduleID, formData);
  294. });
  295. }
  296. /**
  297. * 处理保存文档的操作请求,向服务器发送请求并返回保存的文档对象。
  298. * Handle the save doc operation request, send a request to the server and return the saved doc object.
  299. */
  300. function handleSaveDoc(doc)
  301. {
  302. const docApp = getDocApp();
  303. const spaceType = docApp.signals.spaceType.value;
  304. const libID = docApp.signals.libID.value;
  305. const moduleID = docApp.signals.moduleID.value;
  306. const url = $.createLink('doc', 'editTemplate', `docID=${doc.id}`);
  307. const docData = {
  308. rawContent : doc.content,
  309. status : doc.status || 'normal',
  310. contentType : doc.contentType,
  311. type : 'text',
  312. lib : libID,
  313. module : moduleID,
  314. title : doc.title,
  315. keywords : doc.keywords,
  316. templateDesc : doc.templateDesc,
  317. acl : doc.acl,
  318. content : doc.html,
  319. isDeliverable : doc.isDeliverable || '0',
  320. space : spaceType,
  321. uid : (doc.uid || `doc${doc.id}`),
  322. };
  323. const docAppData = docApp.doc.data;
  324. if (doc.id === docAppData.id) docData.mailto = docAppData.mailto;
  325. if(savingDocData[doc.id])
  326. {
  327. mergeDocFormData(docData, savingDocData[doc.id]);
  328. delete savingDocData[doc.id];
  329. }
  330. return new Promise((resolve) => {
  331. $.post(url, docData, (res) =>
  332. {
  333. try
  334. {
  335. const data = JSON.parse(res);
  336. if(!checkResponse(data)) return;
  337. if(typeof data !== 'object' || data.result === 'fail')
  338. {
  339. let message = data.message || data.error || getLang('errorOccurred');
  340. if(typeof message === 'object') message = Object.values(message).map(x => Array.isArray(x) ? x.join('\n') : x).join('\n');
  341. throw new Error(message);
  342. }
  343. doc = $.extend({}, doc, docData, data.doc);
  344. const libID = +doc.lib;
  345. const lib = docApp.getLib(libID);
  346. if(!lib)
  347. {
  348. resolve(false);
  349. return loadPage($.createLink('doc', 'view', `docID=${doc.id}`));
  350. }
  351. delete doc.title;
  352. delete doc.keywords;
  353. delete doc.content;
  354. resolve(doc);
  355. }
  356. catch (error)
  357. {
  358. resolve(false);
  359. if(!error.message) return;
  360. zui.Modal.alert(error.message);
  361. }
  362. }).fail(error => {
  363. resolve(false);
  364. showSaveFailedAlert(error);
  365. }).complete(() => {
  366. docApp.isSavingDoc = false;
  367. docApp.props.fetcher = $.createLink('doc', 'ajaxGetSpaceData', `type=template&spaceID=${docAppData.space}&picks={picks}&libID=${docAppData.lib}`);
  368. $(docApp.element).find('[zui-command^="saveDoc"],[zui-command^="saveNewDoc"]').removeAttr('disabled');
  369. const {id, acl, users, addedBy} = doc;
  370. if(acl == 'private' && addedBy !== currentUser)
  371. {
  372. if(docApp.hasEditingDoc)
  373. {
  374. docApp.cancelEditDoc().then(() => {
  375. docApp.delete('doc', id);
  376. });
  377. }
  378. else
  379. {
  380. docApp.delete('doc', id);
  381. }
  382. }
  383. docApp.load(null, null, null, {noLoading: false, picks: 'doc'});
  384. });
  385. });
  386. }
  387. const customRenders =
  388. {
  389. home: function()
  390. {
  391. const homeViewUrl = $.createLink('doc', 'browseTemplate', `libID=0&filterType=all&docID=0&orderBy=&recPerPage=20&pageID=1&mode=home`);
  392. return {fetcher: homeViewUrl, clearBeforeLoad: false, className: 'doc-template-home h-full', class: 'h-full col',htmlRender: (element, props) => $(element).morphInner(`<div class="lazy-content doc-template-home h-full">${props.html}</div>`)};
  393. },
  394. /**
  395. * 定义 API 文档列表工具栏渲染。
  396. * Define the API doc list toolbar render.
  397. */
  398. toolbar: function()
  399. {
  400. if(this.mode === 'list')
  401. {
  402. const items = [];
  403. if(docAppHasPriv('create')) items.push({text: getDocAppLang('createTemplate'), icon: 'plus', btnType: 'primary', command: 'startCreateTemplate'});
  404. return {component: 'toolbar', props: {items: items}};
  405. }
  406. },
  407. 'sidebar-footer-hint': function()
  408. {
  409. return '';
  410. }
  411. }
  412. /**
  413. * 定义文档模板各个视图和 UI 元素的上的操作方法。
  414. * Define the operation methods on the views and UI elements of the doc template.
  415. */
  416. $.extend(window.docAppActions,
  417. {
  418. /**
  419. * 定义分组的操作按钮。
  420. * Define the actions on the type group.
  421. */
  422. module: function(info)
  423. {
  424. const items = [];
  425. const module = info.data;
  426. const lang = getLang();
  427. if(docAppHasPriv('addModule')) items.push({text: lang.actions.addSameModule, command: `addModule/${module.root}/${module.parent}`});
  428. if(module.grade == 1 && docAppHasPriv('editModule')) items.push({text: lang.actions.addSubModule, command: `addModule/${module.root}/${module.id}`});
  429. if(docAppHasPriv('editModule')) items.push({text: lang.actions.editModule, command: `editModule/${module.id}`});
  430. if(docAppHasPriv('deleteModule')) items.push({text: lang.actions.deleteModule, command: `deleteModule/${module.id}`});
  431. if(info.ui === 'sidebar')
  432. {
  433. return [
  434. items.length ? {icon: 'ellipsis-v', caret: false, placement: 'bottom-end', size: 'xs', items: items} : null,
  435. ];
  436. }
  437. return items;
  438. },
  439. /**
  440. * 定义文档库的操作按钮。
  441. * Define the actions of modules.
  442. */
  443. lib: function(info)
  444. {
  445. const lang = getLang();
  446. const items = [];
  447. const lib = info.data;
  448. const libID = lib?.data == undefined ? lib?.id : lib?.data.id;
  449. /* 获取侧边栏没有模块时的操作按钮。 Get actions when sidebar no module. */
  450. if(info.ui === 'sidebar-no-module')
  451. {
  452. if(!docAppHasPriv('addModule')) return;
  453. return [{text: lang.actions.addModule, command: `addModule/${libID}/0/${libID}/child`, icon: 'plus', type: 'primary-pale'}];
  454. }
  455. if(docAppHasPriv('addModule')) items.push({text: lang.actions.addModule, command: `addModule/${libID}/0/${libID}/child`});
  456. if(!items.length) return;
  457. return [{type: 'dropdown', icon: 'cog-outline', square: true, caret: false, placement: 'top-end', items: items}];
  458. },
  459. /**
  460. * 定义文档编辑时的操作按钮。
  461. * Define the actions on toolbar of the doc editing page.
  462. */
  463. 'doc-edit': function(info)
  464. {
  465. const doc = info.data;
  466. if(!doc) return;
  467. const lang = getLang();
  468. const isToolbar = info.ui === 'toolbar';
  469. const docApp = this;
  470. return [
  471. isToolbar ? {hint: docApp.fullscreen ? lang.exitFullscreen : lang.enterFullscreen, icon: docApp.fullscreen ? 'fullscreen-exit' : 'fullscreen', command: 'toggleFullscreen'} : null,
  472. (isToolbar && docApp.props.showDocHistory !== false) ? {hint: lang.history, icon: 'file-log', command: 'toggleViewSideTab/history'} : null,
  473. doc.status === 'draft' ? {text: lang.saveDraft, size: 'md', className: 'btn-wide', type: 'secondary', command: 'saveDoc/draft'} : null,
  474. {text: lang.release, size: 'md', className: 'btn-wide', type: 'primary', command: 'saveDoc'},
  475. {text: lang.cancel, size: 'md', className: 'btn-wide', type: 'primary-outline', command: 'cancelEditDoc'},
  476. {text: lang.settings, size: 'md', type: 'ghost', command: `showDocSettingModal/${doc.id}/template/1`, icon: 'cog-outline'},
  477. ];
  478. },
  479. /**
  480. * 定义模板列表的操作按钮。
  481. * Define the actions on the template list.
  482. */
  483. 'doc-list': function(info)
  484. {
  485. const lang = getLang();
  486. const canCreateDoc = hasPriv('create');
  487. /* 文档列表没有文档时的按钮。Actions for empty doc list. */
  488. if(info.ui === 'doc-list-empty')
  489. {
  490. return canCreateDoc ? [{icon: 'plus', text: lang.createTemplate, btnType: 'primary', command: 'startCreateTemplate'}] : null;
  491. }
  492. const items = [];
  493. if(canCreateDoc) items.push({text: lang.createTemplate, icon: 'plus', btnType: 'primary', command: 'startCreateTemplate'});
  494. return items.length ? {component: 'toolbar', props: {items: items}} : null;
  495. }
  496. });
  497. /**
  498. * 处理文档应用销毁事件,销毁文档基本信息对话框。
  499. * Handle the doc app destroy event, destroy the doc basic info dialog.
  500. */
  501. function handleDocAppDestroy()
  502. {
  503. if(docBasicModal.current)
  504. {
  505. docBasicModal.current.destroy();
  506. docBasicModal = {};
  507. }
  508. }
  509. /**
  510. * 重写文档应用的配置选项方法。
  511. * Override the method to set the doc app options.
  512. */
  513. window._setDocAppOptions = window.setDocAppOptions; // Save the original method.
  514. window.setDocAppOptions = function(_, options) // Override the method.
  515. {
  516. options = window._setDocAppOptions(_, options);
  517. currentUser = options.currentUser;
  518. return $.extend(options,
  519. {
  520. onCreateDoc : handleCreateDoc,
  521. onSaveDoc : handleSaveDoc,
  522. getTableOptions : getTableOptions,
  523. customRenders : $.extend(docAppCustomRenders, customRenders),
  524. $onDestroy : handleDocAppDestroy,
  525. });
  526. };
  527. /* 扩展文档模板命令定义。 Extend the doc app command definition. */
  528. $.extend(window.docAppCommands,
  529. {
  530. startCreateTemplate: function(_, args)
  531. {
  532. const docApp = getDocApp();
  533. const lib = docApp.lib;
  534. if(!lib || !lib.modules.length) return zui.Modal.alert(getLang('createTypeFirst'));
  535. const {spaceID, libID, moduleID} = docApp;
  536. return showDocBasicModal(args?.[0] ?? 0, 0, true, 'doc').then((formData) => {
  537. zui.Editor.loadModule().then(() => {
  538. const emptyDoc = zui.Editor.createEmptyDoc();
  539. const snapshot = zui.Editor.toSnapshot(emptyDoc);
  540. const doc = {contentType: 'doc', status: 'draft', content: JSON.stringify(snapshot)};
  541. return submitNewDoc(doc, 0, libID, moduleID, formData, (newDoc) => {
  542. docApp.selectDoc(newDoc.id);
  543. docApp.startEditDoc(newDoc.id);
  544. });
  545. });
  546. });
  547. },
  548. addChapter: function(_, args)
  549. {
  550. const docApp = getDocApp();
  551. const {spaceID, libID, moduleID} = docApp;
  552. return showDocBasicModal(args[0], 0, false, 'chapter').then((formData) => {
  553. const doc = {type: 'chapter', status: 'normal', parent: args[0]};
  554. return submitNewDoc(doc, spaceID, libID, moduleID, formData).then(() => {
  555. docApp.load(null, null, null, {noLoading: false, picks: 'doc'});
  556. if(docBasicModal.current)
  557. {
  558. docBasicModal.current.destroy();
  559. docBasicModal = {};
  560. }
  561. });
  562. });
  563. },
  564. editChapter: function(_, args)
  565. {
  566. const docApp = getDocApp();
  567. return showDocBasicModal(docApp.doc.data.parent, args[0], false, 'chapter').then((formData) => {
  568. return submitEditDoc(formData);
  569. });
  570. },
  571. deleteDoc: function(_, args)
  572. {
  573. const docApp = getDocApp();
  574. const docID = args[0] || docApp.docID;
  575. const docInfo = docApp.treeMap.docs.get(docID)
  576. const doc = docInfo.data;
  577. const isChapter = doc?.type === 'chapter';
  578. $.ajaxSubmit(
  579. {
  580. confirm: getLang(isChapter ? (docInfo.docs.length > 0 ? 'confirmDeleteChapterWithSub' : 'confirmDeleteChapter') : (docInfo.docs.length > 0 ? 'confirmDeleteWithSub' : 'confirmDelete')),
  581. url: $.createLink('doc', 'deleteTemplate', `docID=${docID}`),
  582. load: false,
  583. onSuccess: function()
  584. {
  585. getDocApp().delete('doc', docID);
  586. }
  587. });
  588. },
  589. moveDoc: function(_, args)
  590. {
  591. const docApp = getDocApp();
  592. const docID = args[0] || docApp.docID;
  593. const url = $.createLink('doc', 'moveTemplate', `docID=${docID}`);
  594. zui.Modal.open({size: 'sm', url: url});
  595. },
  596. addModule: function(_, args)
  597. {
  598. const docApp = getDocApp();
  599. const scope = args[0];
  600. const parentModule = args[1];
  601. const url = $.createLink('doc', 'addTemplateType', `scope=${scope}&parentModule=${parentModule}`);
  602. zui.Modal.open({size: 'sm', url: url});
  603. },
  604. editModule: function(_, args)
  605. {
  606. const docApp = getDocApp();
  607. const moduleID = args[0] || docApp.moduleID;
  608. const url = $.createLink('doc', 'editTemplateType', `moduleID=${moduleID}`);
  609. zui.Modal.open({size: 'sm', url: url});
  610. },
  611. deleteModule: function(_, args)
  612. {
  613. const docApp = getDocApp();
  614. const moduleID = args[0] || docApp.moduleID;
  615. $.ajaxSubmit(
  616. {
  617. url: $.createLink('doc', 'deleteTemplateType', `moduleID=${moduleID}`),
  618. load: false,
  619. onSuccess: function()
  620. {
  621. getDocApp().delete('module', moduleID);
  622. }
  623. })
  624. },
  625. /**
  626. * 编辑文档模板。
  627. * Edit doc template.
  628. */
  629. editTemplate: function(_, args)
  630. {
  631. const docApp = getDocApp();
  632. const templateID = args[0] || docApp.docID;
  633. const url = $.createLink('doc', 'editTemplate', `templateID=${templateID}`);
  634. zui.Modal.open({size: 'sm', url: url});
  635. },
  636. /**
  637. * 删除文档模板。
  638. * Delete doc template.
  639. */
  640. deleteTemplate: function(_, args)
  641. {
  642. const docApp = getDocApp();
  643. const lang = getDocAppLang();
  644. const templateID = args[0] || docApp.docID;
  645. $.ajaxSubmit(
  646. {
  647. confirm: lang.confirmDelete,
  648. url: $.createLink('doc', 'deleteTemplate', `templateID=${templateID}`),
  649. load:false,
  650. onSunccess: function()
  651. {
  652. getDocApp().delete('doc', templateID);
  653. }
  654. })
  655. },
  656. showDocSettingModal: showDocSettingModal
  657. });
  658. window.clickTemplateCard = function(event, url)
  659. {
  660. const target = $(event.target);
  661. if(target.hasClass('icon') || target.hasClass('dropdown') || target.hasClass('toolbar')) return;
  662. openUrl(url);
  663. }