function createOpportunitiesTable({ ACCOUNT_DETAIL_URL, OPPORTUNITIES_COLUMNS, OPPORTUNITIES_TABLE_ID, OPPORTUNITY_DETAIL_URL, createCloudConsumptionButton, createInstallBaseButton, createServiceRequestsButton, createCopyOpportunityButton, createDetailLink, createProductsCountButton, createProductsRampBadge, createProjectionIndicator, createCrmServiceRequestBadge, closeCrmSrPopover, createWorkloadActionsBadge, createProductsDetailRow, createStageBadge, createStatusBadge, displayOpportunityValue, getNestedValue, getSortedOpportunities, opportunitiesTableState, productsContentState, renderCustomerFilter, renderOwnerFilter, renderActivityFilters, renderStageDashboard, renderCalendar, resetCustomerFilter, resetOwnerFilter, environment }) { const { document } = environment; function setOpportunitiesTableState(nextState) { if (nextState.status === "ready" && Array.isArray(nextState.items)) { resetCustomerFilter(nextState.items); resetOwnerFilter(nextState.items); } opportunitiesTableState.opportunitiesTableState = { ...opportunitiesTableState.opportunitiesTableState, ...nextState, sortKey: nextState.items ? "" : opportunitiesTableState.opportunitiesTableState.sortKey, sortDirection: nextState.items ? "ascending" : opportunitiesTableState.opportunitiesTableState.sortDirection }; renderOpportunitiesTable(); renderCustomerFilter(); renderOwnerFilter(); } function renderOpportunitiesTable() { renderActivityFilters(); const table = document.getElementById(OPPORTUNITIES_TABLE_ID); if (!table) { return; } closeCrmSrPopover(); table.textContent = ""; table.setAttribute("data-opportunities-layout", "inline-actions"); table.setAttribute("aria-busy", opportunitiesTableState.opportunitiesTableState.status === "loading" ? "true" : "false"); const caption = document.createElement("caption"); caption.className = "opportunities-extension-visually-hidden"; caption.textContent = "Opportunities"; const tableHead = document.createElement("thead"); const headerRow = document.createElement("tr"); OPPORTUNITIES_COLUMNS.forEach((column) => { const header = document.createElement("th"); const isSorted = opportunitiesTableState.opportunitiesTableState.sortKey === column.key; header.scope = "col"; header.setAttribute("data-column", column.key); if (column.sortable === false) { const label = document.createElement("span"); label.className = "opportunities-extension-table-header-label"; label.textContent = column.label; header.append(label); } else { header.setAttribute("aria-sort", isSorted ? opportunitiesTableState.opportunitiesTableState.sortDirection : "none"); const sortButton = document.createElement("button"); sortButton.type = "button"; sortButton.className = "opportunities-extension-sort-button"; sortButton.setAttribute("data-sort-direction", isSorted ? opportunitiesTableState.opportunitiesTableState.sortDirection : "none"); sortButton.setAttribute("aria-label", `Sort by ${column.label}${isSorted ? `, ${opportunitiesTableState.opportunitiesTableState.sortDirection}` : ""}`); const sortLabel = document.createElement("span"); sortLabel.className = "opportunities-extension-sort-label"; sortLabel.textContent = column.label; sortButton.append(sortLabel); sortButton.addEventListener("click", () => sortOpportunitiesBy(column.key)); header.append(sortButton); } headerRow.append(header); }); tableHead.append(headerRow); const tableBody = document.createElement("tbody"); const items = getSortedOpportunities(); renderStageDashboard(items, opportunitiesTableState.opportunitiesTableState.items.length); renderCalendar?.(items, opportunitiesTableState.opportunitiesTableState); if (opportunitiesTableState.opportunitiesTableState.status === "loading" || opportunitiesTableState.opportunitiesTableState.status === "error" || opportunitiesTableState.opportunitiesTableState.status === "empty" || (opportunitiesTableState.opportunitiesTableState.status === "ready" && items.length === 0)) { const row = document.createElement("tr"); const cell = document.createElement("td"); cell.className = "opportunities-extension-table-status"; cell.colSpan = OPPORTUNITIES_COLUMNS.length; cell.textContent = opportunitiesTableState.opportunitiesTableState.message || "No opportunities found."; row.append(cell); tableBody.append(row); } else { items.forEach((item) => { const row = document.createElement("tr"); OPPORTUNITIES_COLUMNS.forEach((column) => { const cell = document.createElement("td"); cell.setAttribute("data-column", column.key); if (column.key === "stage") { cell.append(createStageBadge(column.display(item))); } else if (column.key === "status") { cell.append(createStatusBadge(column.display(item))); } else if (column.key === "name" || column.key === "optyNumber") { const opportunityLink = createDetailLink( column.display(item), item.OptyNumber ? `${OPPORTUNITY_DETAIL_URL}${encodeURIComponent(item.OptyNumber)}` : "" ); if (column.key === "name") { const nameCellContent = document.createElement("span"); nameCellContent.className = "opportunities-extension-cell-content"; const productActions = document.createElement("span"); productActions.className = "opportunities-extension-cell-actions"; const productsResult = item.OptyNumber && productsContentState.opptyProductsByNumber.get(String(item.OptyNumber)); if (productsResult) { productActions.append(createProductsCountButton(item.OptyNumber, productsResult)); const rampBadge = createProductsRampBadge(productsResult); if (rampBadge) productActions.append(rampBadge); } const srBadge = createCrmServiceRequestBadge(item.OptyNumber); if (srBadge) productActions.append(srBadge); const actionsBadge = createWorkloadActionsBadge(item.OptyNumber); if (actionsBadge) productActions.append(actionsBadge); const projectionIndicator = createProjectionIndicator(productsResult, item, productsContentState.expandedProductOptyNumbers.has(String(item.OptyNumber))); if (projectionIndicator) productActions.append(projectionIndicator); nameCellContent.append(opportunityLink, productActions); cell.append(nameCellContent); } else if (column.key === "optyNumber" && item.OptyNumber) { const opportunityCellContent = document.createElement("span"); opportunityCellContent.className = "opportunities-extension-opty-number-content"; opportunityCellContent.append(opportunityLink, createCopyOpportunityButton(item.OptyNumber)); cell.append(opportunityCellContent); } else { cell.append(opportunityLink); } } else if (column.key === "customer") { const customerCellContent = document.createElement("span"); customerCellContent.className = "opportunities-extension-cell-content"; const customerLink = createDetailLink( column.display(item), getNestedValue(item, ["CustomerAccount", "PartyId"]) ? `${ACCOUNT_DETAIL_URL}${encodeURIComponent(getNestedValue(item, ["CustomerAccount", "PartyId"]))}` : "" ); const customerActions = document.createElement("span"); customerActions.className = "opportunities-extension-cell-actions"; customerActions.append(createCloudConsumptionButton(item), createInstallBaseButton(item), createServiceRequestsButton(item)); customerCellContent.append(customerLink, customerActions); cell.append(customerCellContent); } else { cell.textContent = displayOpportunityValue(column, item); } row.append(cell); }); tableBody.append(row); if (item.OptyNumber && productsContentState.expandedProductOptyNumbers.has(String(item.OptyNumber))) { tableBody.append(createProductsDetailRow(item)); } }); } table.append(caption, tableHead, tableBody); } function sortOpportunitiesBy(key) { const isSameColumn = opportunitiesTableState.opportunitiesTableState.sortKey === key; opportunitiesTableState.opportunitiesTableState.sortKey = key; opportunitiesTableState.opportunitiesTableState.sortDirection = isSameColumn && opportunitiesTableState.opportunitiesTableState.sortDirection === "ascending" ? "descending" : "ascending"; renderOpportunitiesTable(); } return { setOpportunitiesTableState, renderOpportunitiesTable, sortOpportunitiesBy }; }