185 lines
7.9 KiB
JavaScript
185 lines
7.9 KiB
JavaScript
function createOpportunitiesTable({
|
|
ACCOUNT_DETAIL_URL,
|
|
OPPORTUNITIES_COLUMNS,
|
|
OPPORTUNITIES_TABLE_ID,
|
|
OPPORTUNITY_DETAIL_URL,
|
|
createCloudConsumptionButton,
|
|
createInstallBaseButton,
|
|
createServiceRequestsButton,
|
|
createCopyOpportunityButton,
|
|
createDetailLink,
|
|
createProductsCountButton,
|
|
createProductsDetailRow,
|
|
createStageBadge,
|
|
createStatusBadge,
|
|
displayOpportunityValue,
|
|
getNestedValue,
|
|
getSortedOpportunities,
|
|
opportunitiesTableState,
|
|
productsContentState,
|
|
renderCustomerFilter,
|
|
renderOwnerFilter,
|
|
renderStageDashboard,
|
|
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() {
|
|
const table = document.getElementById(OPPORTUNITIES_TABLE_ID);
|
|
|
|
if (!table) {
|
|
return;
|
|
}
|
|
|
|
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);
|
|
|
|
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));
|
|
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 };
|
|
}
|