mirror of https://github.com/jenkinsci/jenkins.git
220 lines
6.2 KiB
JavaScript
220 lines
6.2 KiB
JavaScript
import Path from "@/util/path";
|
|
import behaviorShim from "@/util/behavior-shim";
|
|
import Utils from "@/components/dropdowns/utils";
|
|
|
|
function init() {
|
|
generateJumplistAccessors();
|
|
generateDropdowns();
|
|
}
|
|
|
|
/*
|
|
* Appends a ⌄ button at the end of links which support jump lists
|
|
*/
|
|
function generateJumplistAccessors() {
|
|
behaviorShim.specify("A.model-link", "-jumplist-", 999, (link) => {
|
|
const isFirefox = navigator.userAgent.indexOf("Firefox") !== -1;
|
|
// Firefox adds unwanted lines when copying buttons in text, so use a span instead
|
|
const dropdownChevron = document.createElement(
|
|
isFirefox ? "span" : "button",
|
|
);
|
|
dropdownChevron.className = "jenkins-menu-dropdown-chevron";
|
|
dropdownChevron.dataset.href = link.href;
|
|
dropdownChevron.addEventListener("click", (event) => {
|
|
event.preventDefault();
|
|
});
|
|
link.appendChild(dropdownChevron);
|
|
});
|
|
}
|
|
|
|
/*
|
|
* Generates the dropdowns for the jump lists
|
|
*/
|
|
function generateDropdowns() {
|
|
behaviorShim.specify(
|
|
".hoverable-model-link, .hoverable-children-model-link",
|
|
"-hoverable-dropdown-",
|
|
1000,
|
|
(element) =>
|
|
Utils.generateDropdown(
|
|
element,
|
|
(instance) => {
|
|
if (element.items) {
|
|
instance.setContent(Utils.generateDropdownItems(element.items));
|
|
return;
|
|
}
|
|
|
|
const href = element.href;
|
|
|
|
const hasModelLink = element.classList.contains(
|
|
"hoverable-model-link",
|
|
);
|
|
const hasChildrenLink = element.classList.contains(
|
|
"hoverable-children-model-link",
|
|
);
|
|
|
|
const sections = {
|
|
model: null,
|
|
children: null,
|
|
};
|
|
|
|
const fetchSection = function (urlSuffix) {
|
|
return fetch(Path.combinePath(href, urlSuffix))
|
|
.then((response) => response.json())
|
|
.then((json) => {
|
|
const items = mapChildrenItemsToDropdownItems(json.items);
|
|
const section = document.createElement("div");
|
|
section.appendChild(Utils.generateDropdownItems(items));
|
|
return section;
|
|
});
|
|
};
|
|
|
|
const promises = [];
|
|
|
|
if (hasModelLink) {
|
|
promises.push(
|
|
fetchSection("contextMenu").then((section) => {
|
|
sections.model = section;
|
|
}),
|
|
);
|
|
}
|
|
|
|
if (hasChildrenLink) {
|
|
promises.push(
|
|
fetchSection("childrenContextMenu").then((section) => {
|
|
sections.children = section;
|
|
}),
|
|
);
|
|
}
|
|
|
|
Promise.all(promises)
|
|
.then(() => {
|
|
const container = document.createElement("div");
|
|
container.className = "jenkins-dropdown__split-container";
|
|
if (sections.model) {
|
|
container.appendChild(sections.model);
|
|
}
|
|
if (sections.children) {
|
|
container.appendChild(sections.children);
|
|
}
|
|
instance.setContent(container);
|
|
})
|
|
.catch((error) => {
|
|
console.log(`Dropdown fetch failed: ${error}`);
|
|
})
|
|
.finally(() => {
|
|
instance.loaded = true;
|
|
});
|
|
},
|
|
element.items != null,
|
|
{
|
|
trigger: "mouseenter",
|
|
offset: [-16, 10],
|
|
animation: "tooltip",
|
|
touch: false,
|
|
},
|
|
),
|
|
);
|
|
|
|
behaviorShim.specify(
|
|
"li.children, .jenkins-jumplist-link, #menuSelector, .jenkins-menu-dropdown-chevron",
|
|
"-dropdown-",
|
|
1000,
|
|
(element) =>
|
|
Utils.generateDropdown(element, (instance) => {
|
|
const href = element.dataset.href;
|
|
|
|
const jumplistType = !element.classList.contains("children")
|
|
? "contextMenu"
|
|
: "childrenContextMenu";
|
|
|
|
if (element.items) {
|
|
instance.setContent(Utils.generateDropdownItems(element.items));
|
|
return;
|
|
}
|
|
|
|
fetch(Path.combinePath(href, jumplistType))
|
|
.then((response) => response.json())
|
|
.then((json) =>
|
|
instance.setContent(
|
|
Utils.generateDropdownItems(
|
|
mapChildrenItemsToDropdownItems(json.items),
|
|
),
|
|
),
|
|
)
|
|
.catch((error) => console.log(`Jumplist request failed: ${error}`))
|
|
.finally(() => (instance.loaded = true));
|
|
}),
|
|
);
|
|
}
|
|
|
|
/*
|
|
* Generates the contents for the dropdown
|
|
*/
|
|
function mapChildrenItemsToDropdownItems(items) {
|
|
return items.map((item) => {
|
|
if (item.type === "HEADER") {
|
|
return {
|
|
type: "HEADER",
|
|
label: item.displayName,
|
|
};
|
|
}
|
|
|
|
if (item.type === "SEPARATOR") {
|
|
return {
|
|
type: "SEPARATOR",
|
|
};
|
|
}
|
|
|
|
return {
|
|
icon: item.icon,
|
|
iconXml: item.iconXml,
|
|
label: item.displayName,
|
|
url: item.url,
|
|
type: item.post || item.requiresConfirmation ? "button" : "link",
|
|
badge: item.badge,
|
|
onClick: () => {
|
|
if (item.post || item.requiresConfirmation) {
|
|
if (item.requiresConfirmation) {
|
|
dialog
|
|
.confirm(item.displayName, { message: item.message })
|
|
.then(() => {
|
|
const form = document.createElement("form");
|
|
form.setAttribute("method", item.post ? "POST" : "GET");
|
|
form.setAttribute("action", item.url);
|
|
if (item.post) {
|
|
crumb.appendToForm(form);
|
|
}
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
});
|
|
} else {
|
|
fetch(item.url, {
|
|
method: "post",
|
|
headers: crumb.wrap({}),
|
|
}).then((rsp) => {
|
|
if (rsp.ok) {
|
|
notificationBar.show(
|
|
item.displayName + ": Done.",
|
|
notificationBar.SUCCESS,
|
|
);
|
|
} else {
|
|
notificationBar.show(
|
|
item.displayName + ": Failed.",
|
|
notificationBar.ERROR,
|
|
);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
subMenu: item.subMenu
|
|
? () => {
|
|
return mapChildrenItemsToDropdownItems(item.subMenu.items);
|
|
}
|
|
: null,
|
|
};
|
|
});
|
|
}
|
|
|
|
export default { init };
|