function createConsumptionPlansAction({ messageTypes, appendBackgroundRequestLog, consumptionPlansState, getNestedValue, openAccountPlansModal, renderOpportunitiesTable, requestConsumerTokenServiceOnce, sendRuntimeMessage, showCopyConfirmation, environment }) { const { document } = environment; function createCloudConsumptionButton(opportunity) { const button = document.createElement("button"); const optyNumber = String(opportunity.OptyNumber || ""); const partyNumber = getNestedValue(opportunity, ["CustomerAccount", "PartyNumber"]); const requestState = consumptionPlansState.accountPlansRequestState.get(optyNumber); const isLoading = requestState && requestState.status === "loading"; button.type = "button"; button.className = "opportunities-extension-action-button"; button.setAttribute("aria-label", `View cloud consumption for ${optyNumber || "opportunity"}`); button.title = isLoading ? "Loading customer consumption" : "View customer consumption"; button.disabled = Boolean(isLoading); button.classList.toggle("opportunities-extension-action-button-loading", Boolean(isLoading)); button.append(createCloudConsumptionIcon()); button.addEventListener("click", () => { if (!partyNumber) { showCopyConfirmation("Customer Party Number is unavailable.", true); return; } const currentRequests = consumptionPlansState.accountPlansRequestState; currentRequests.set(optyNumber, { status: "loading" }); openAccountPlansModal(opportunity, [], "loading"); renderOpportunitiesTable(); requestConsumerTokenServiceOnce() .then((authorizations) => sendRuntimeMessage({ type: messageTypes.requestAccountPlans, partyNumber: String(partyNumber), authorizations })) .then((response) => { if (consumptionPlansState.accountPlansRequestState !== currentRequests) return; appendBackgroundRequestLog(response && response.debugRequests); if (!response || !response.ok) { throw new Error(response && response.error ? response.error : "Unable to load cloud consumption."); } consumptionPlansState.accountPlansRequestState.set(optyNumber, { status: "ready", plans: Array.isArray(response.plans) ? response.plans : [] }); renderOpportunitiesTable(); openAccountPlansModal(opportunity, response.plans || [], "ready"); }).catch((error) => { if (consumptionPlansState.accountPlansRequestState !== currentRequests) return; const errorMessage = error.message || "Unable to load cloud consumption."; consumptionPlansState.accountPlansRequestState.set(optyNumber, { status: "error", error: errorMessage }); renderOpportunitiesTable(); openAccountPlansModal(opportunity, [], "error", errorMessage); showCopyConfirmation(errorMessage, true); }); }); return button; } function createCloudConsumptionIcon() { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); const cloud = document.createElementNS("http://www.w3.org/2000/svg", "path"); const usage = document.createElementNS("http://www.w3.org/2000/svg", "path"); svg.setAttribute("viewBox", "0 0 24 24"); svg.setAttribute("aria-hidden", "true"); svg.setAttribute("focusable", "false"); cloud.setAttribute("d", "M7.2 18.5h10.1a4.2 4.2 0 0 0 .5-8.37A6.25 6.25 0 0 0 5.9 8.75a4.9 4.9 0 0 0 1.3 9.75Z"); usage.setAttribute("d", "M9 15v-2m3 2v-4m3 4V9"); [cloud, usage].forEach((path) => { path.setAttribute("fill", "none"); path.setAttribute("stroke", "currentColor"); path.setAttribute("stroke-linecap", "round"); path.setAttribute("stroke-linejoin", "round"); path.setAttribute("stroke-width", "1.7"); }); svg.append(cloud, usage); return svg; } return { createCloudConsumptionButton, createCloudConsumptionIcon }; }