OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)
This commit is contained in:
169
public/assets/js/app/core/modals.js
Normal file
169
public/assets/js/app/core/modals.js
Normal file
@@ -0,0 +1,169 @@
|
||||
leantime.modals = (function () {
|
||||
|
||||
// The URL of the modal currently open. Used to make the hashchange->openModal
|
||||
// path idempotent: a repeated hashchange pointing at the already-open modal
|
||||
// must NOT rebuild it. Rebuilding re-fetches and re-inserts the whole
|
||||
// .nyroModalCont, destroying any field the user is typing into (focus loss).
|
||||
var currentModalUrl = null;
|
||||
|
||||
var setCustomModalCallback = function(callback) {
|
||||
if(typeof callback === 'function') {
|
||||
window.globalModalCallback = callback;
|
||||
}
|
||||
}
|
||||
var openModal = function () {
|
||||
|
||||
var modalOptions = {
|
||||
sizes: {
|
||||
minW: 500,
|
||||
minH: 200
|
||||
},
|
||||
resizable: true,
|
||||
autoSizable: true,
|
||||
callbacks: {
|
||||
beforePostSubmit: function () {
|
||||
|
||||
jQuery(".showDialogOnLoad").show();
|
||||
|
||||
// Destroy Tiptap editors
|
||||
if(window.leantime?.tiptapController?.registry) {
|
||||
var count = window.leantime.tiptapController.registry.destroyAll();
|
||||
if(count > 0) {
|
||||
console.log('[Modal] Destroyed', count, 'Tiptap editor(s)');
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
beforeShowCont: function () {
|
||||
jQuery(".showDialogOnLoad").show();
|
||||
|
||||
// Destroy Tiptap editors
|
||||
if(window.leantime?.tiptapController?.registry) {
|
||||
window.leantime.tiptapController.registry.destroyAll();
|
||||
}
|
||||
|
||||
},
|
||||
afterShowCont: function () {
|
||||
window.htmx.process('.nyroModalCont');
|
||||
jQuery(".formModal, .modal").nyroModal(modalOptions);
|
||||
// Idempotent + scoped to the modal so it doesn't re-instance
|
||||
// page tooltips (see app.js initTooltips).
|
||||
window.leantime?.initTooltips?.(document.querySelector('.nyroModalCont'));
|
||||
|
||||
// Initialize Tiptap editors in modal (after small delay for DOM settlement)
|
||||
setTimeout(function() {
|
||||
if(window.leantime?.tiptapController?.initEditors) {
|
||||
var modalContent = document.querySelector('.nyroModalCont');
|
||||
if(modalContent) {
|
||||
window.leantime.tiptapController.initEditors(modalContent);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
beforeClose: function () {
|
||||
currentModalUrl = null;
|
||||
try{
|
||||
history.pushState("", document.title, window.location.pathname + window.location.search);
|
||||
|
||||
}catch(error){
|
||||
//Code to handle error comes here
|
||||
console.log("Issue pushing history");
|
||||
}
|
||||
|
||||
if(typeof window.globalModalCallback === 'function') {
|
||||
window.globalModalCallback();
|
||||
}else{
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
},
|
||||
titleFromIframe: true
|
||||
};
|
||||
|
||||
var url = window.location.hash.substring(1);
|
||||
if(url.includes("showTicket")
|
||||
|| url.includes("ideaDialog")
|
||||
|| url.includes("articleDialog")) {
|
||||
// These detail modals are intentionally large on desktop. On
|
||||
// mobile/tablet (<1200px) the 1800px minimum makes them unusable,
|
||||
// so only apply it on desktop. CSS caps the container to ~95vw. #3088
|
||||
if (window.innerWidth >= 1200) {
|
||||
modalOptions.sizes.minW = 1800;
|
||||
modalOptions.sizes.minH = 1800;
|
||||
}
|
||||
}
|
||||
|
||||
// Never let any modal's minimum width exceed the viewport on small
|
||||
// screens, otherwise it forces horizontal overflow. #3088
|
||||
if (window.innerWidth < 1200) {
|
||||
modalOptions.sizes.minW = Math.min(modalOptions.sizes.minW, window.innerWidth - 20);
|
||||
}
|
||||
|
||||
//Ensure we have no trailing slash at the end.
|
||||
var baseUrl = leantime.appUrl.replace(/\/$/, '');
|
||||
|
||||
var urlParts = url.split("/");
|
||||
if(urlParts.length>2 && urlParts[1] !== "tab") {
|
||||
var targetUrl = baseUrl+""+url;
|
||||
|
||||
// Idempotency guard: if the modal for this exact URL is already open, a
|
||||
// repeated hashchange must NOT rebuild it — rebuilding destroys the DOM
|
||||
// (and any input the user is typing into), stealing focus.
|
||||
if (targetUrl === currentModalUrl && jQuery.nmTop()) {
|
||||
return;
|
||||
}
|
||||
currentModalUrl = targetUrl;
|
||||
|
||||
// Guard against nyroModal losing its jQuery registration between opens.
|
||||
// This can happen when the modal close/reinit cycle runs before the
|
||||
// document-ready wrapper in jquery.nyroModal.custom.js has re-fired.
|
||||
if (typeof jQuery.nmManual !== 'function') {
|
||||
console.warn('[Modal] jQuery.nmManual not available, retrying...');
|
||||
setTimeout(function() {
|
||||
if (typeof jQuery.nmManual === 'function') {
|
||||
jQuery.nmManual(targetUrl, modalOptions);
|
||||
} else {
|
||||
console.error('[Modal] jQuery.nmManual unavailable after retry — nyroModal may not be loaded.');
|
||||
}
|
||||
}, 100);
|
||||
return;
|
||||
}
|
||||
jQuery.nmManual(targetUrl, modalOptions);
|
||||
}
|
||||
}
|
||||
|
||||
var closeModal = function () {
|
||||
if( jQuery.nmTop()) {
|
||||
jQuery.nmTop().close();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
openModal:openModal,
|
||||
setCustomModalCallback:setCustomModalCallback,
|
||||
closeModal:closeModal
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
leantime.modals.openModal();
|
||||
});
|
||||
|
||||
window.addEventListener("hashchange", function () {
|
||||
leantime.modals.openModal();
|
||||
});
|
||||
|
||||
// 'lt:ui:modal.close' is the canonical client event. The legacy names ('closeModal',
|
||||
// 'HTMX.closemodal', 'Htmx.CloseModal') are kept for the migration window and also close a
|
||||
// pre-existing gap: emitters used three different casings but only 'closeModal' had a listener.
|
||||
var onCloseModalEvent = function (evt) {
|
||||
leantime.modals.closeModal();
|
||||
};
|
||||
|
||||
window.addEventListener("lt:ui:modal.close", onCloseModalEvent);
|
||||
window.addEventListener("closeModal", onCloseModalEvent);
|
||||
window.addEventListener("HTMX.closemodal", onCloseModalEvent);
|
||||
window.addEventListener("Htmx.CloseModal", onCloseModalEvent);
|
||||
|
||||
Reference in New Issue
Block a user