If attachment > 300 can't copy.
If your company uses Confluence Server/Data Center, make sure to apply and share this tip with the admin. It will fundamentally resolve the issue of Confluence going down (without any apparent reason). Simply copy and paste the following JavaScript code at
<confluence_url>/admin/editcustomhtml.action > At end of the BODY. It only takes 30 seconds.
The core of this code is to prevent the copying of a page if it has more than 300 attachments. When copying a page, the background process of copying all attachments from the original page can significantly impact Confluence's performance. There may even be pages with thousands of attachments. Additionally, no logs are generated.
Typically, a single page shouldn't need more than 300 attachments. You can adjust this 300-attachment threshold to fit your company's situation. By preventing the copying of heavy pages (which is very easy to apply), you can easily resolve the issue of Confluence going down.
<script>
AJS.toInit(function() {
var pageId = AJS.Meta.get("page-id");
function fetchAttachments(start, totalFetched) {
AJS.$.ajax({
url: "/rest/api/content/" + pageId + "/child/attachment?limit=200&start=" + start,
type: "GET",
success: function(data) {
var attachmentCount = data.results.length;
totalFetched += attachmentCount;
if (attachmentCount === 200 && data._links.next) {
fetchAttachments(start + 200, totalFetched);
} else {
displayAttachmentCount(totalFetched);
}
},
error: function(error) {
console.log("Failed to fetch attachment information.", error);
}
});
}
function displayAttachmentCount(count) {
if (count > 30) {
var color = 'black'; // Default color
if (count > 100) {
color = 'red';
} else if (count > 50) {
color = 'blue';
}
AJS.$('#action-menu-link').after('<span id="attachment-count" style="color:' + color + '">(' + count + ')</span>');
document.getElementById('action-copy-page-link').innerHTML = '<span style="color:' + color + '"> Copy (' + count + ')</span>';
}
}
fetchAttachments(0, 0);
});
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var pageId = AJS.Meta.get("page-id");
function fetchAttachments(start, totalFetched) {
AJS.$.ajax({
url: "/rest/api/content/" + pageId + "/child/attachment?limit=200&start=" + start,
type: "GET",
success: function(data) {
var attachmentCount = data.results.length;
totalFetched += attachmentCount;
if (attachmentCount === 200 && data._links.next) {
fetchAttachments(start + 200, totalFetched);
} else {
displayAttachmentCount(totalFetched);
}
},
error: function(error) {
console.log("Failed to fetch attachment information.", error);
}
});
}
function displayAttachmentCount(count) {
// Add event listener for 'Copy' link click.
var copyPageLink = document.getElementById('action-copy-page-link');
if (copyPageLink) {
copyPageLink.addEventListener('click', function() {
setTimeout(function() {
var copyAttachmentsContainer = document.getElementById('copy-attachments-container');
if (copyAttachmentsContainer && count > 30) {
var color = 'black';
if (count > 100) {
color = 'red';
} else if (count > 50) {
color = 'blue';
}
var attachmentCountSpan = document.createElement('span');
attachmentCountSpan.textContent = ' (' + count + ')';
attachmentCountSpan.style.color = color;
copyAttachmentsContainer.appendChild(attachmentCountSpan);
}
}, 500); // 500ms delay
});
}
}
// Start fetching the number of attachments.
fetchAttachments(0, 0);
});
</script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var pageId = AJS.Meta.get("page-id");
function fetchAttachments(start, totalFetched) {
AJS.$.ajax({
url: "/rest/api/content/" + pageId + "/child/attachment?limit=200&start=" + start,
type: "GET",
success: function(data) {
var attachmentCount = data.results.length;
totalFetched += attachmentCount;
if (attachmentCount === 200 && data._links.next) {
fetchAttachments(start + 200, totalFetched);
} else {
processAttachmentCount(totalFetched);
}
},
error: function(error) {
console.log("Failed to fetch attachment information.", error);
}
});
}
function processAttachmentCount(count) {
if (count >= 300) {
// Disable 'Copy' button if there are more than 300 attachments.
var copyPageLink = document.getElementById('action-copy-page-link');
if (copyPageLink) {
copyPageLink.style.pointerEvents = 'none';
copyPageLink.style.opacity = '0.5';
}
}
}
// Start fetching the number of attachments.
fetchAttachments(0, 0);
});
/** Add text to the lock icon */
function add_restrict_text() {
/** Restriction message */
// Get the element
var element = document.getElementById("content-metadata-page-restrictions");
// Get the value of the original-title attribute
var originalTitle = element.getAttribute("title");
// Print the value
console.log(originalTitle);
/** Check for class existence (red color) */
// Get the element
var element = document.getElementById("content-metadata-page-restrictions");
var locked = true;
// Check if the class exists
if (element.classList.contains("aui-iconfont-unlocked")) {
console.log("aui-iconfont-unlocked class exists.");
locked = false;
if(element.classList.contains("restricted")) {
locked = true;
}
}
/**
* originalTitle: Text displayed when hovering over the lock icon
* locked: true==unlocked icon, false==lock icon
*/
var existingElement = document.getElementById("page-banner-end");
// Create a new span element
var newSpanElement = document.createElement("div");
// Add attributes to the new span element (e.g., id and class)
newSpanElement.setAttribute("id", "new-span-id");
newSpanElement.setAttribute("class", "new-span-class");
// Set top margin
newSpanElement.style.marginTop = "10px";
// Add text content to the new span element
newSpanElement.textContent = "No Restrictions";
if(originalTitle == "Restrictions apply" || originalTitle == "제한 적용") {
if(locked) {
newSpanElement.textContent = "View/Edit Restrictions";
newSpanElement.style.color = "red";
} else {
newSpanElement.textContent = "Edit Restrictions";
newSpanElement.style.color = "blue";
}
}
// Insert the new span element after the existing element
existingElement.insertAdjacentElement('afterend', newSpanElement);
}
// Get the target element to observe
var targetElement = document.getElementById("content-metadata-page-restrictions");
// Create a MutationObserver
var observer = new MutationObserver(function(mutations) {
// Call the function to handle class changes
handleClassChange();
});
// Observer configuration
var config = { attributes: true, attributeFilter: ["class"] };
observer.observe(targetElement, config);
// Define the function to handle class changes
function handleClassChange() {
// Write the function or code you want to execute here.
console.log("Class has changed!");
// You can call additional functions or write more code here.
// Get the element
var elementToRemove = document.getElementById("new-span-id");
// Check if the element exists and remove it
if (elementToRemove) {
elementToRemove.parentNode.removeChild(elementToRemove);
} else {
console.log("Element to remove not found.");
}
add_restrict_text();
}
add_restrict_text();
</script>
flex
1 comment