Repositioned the opportunity and customer control buttons

This commit is contained in:
2026-09-22 12:07:12 -03:00
parent eed4189a07
commit 8d73954362
9 changed files with 359 additions and 62 deletions

View File

@@ -9,7 +9,6 @@ function createOpportunitiesColumns({ formatOracleResponseDate, formatRevenue, f
{ key: "status", label: "Status", value: (item) => item.StatusCode, display: (item) => item.StatusCode },
{ key: "winProbability", label: "Win Probability", value: (item) => getNestedValue(item, ["PrimaryRevenue", "WinProb"]), display: formatWinProbability },
{ key: "stage", label: "Stage", value: (item) => item.ForecastGroup_c, display: (item) => item.ForecastGroup_c },
{ key: "lastUpdateDate", label: "Last Update Date", value: (item) => item.LastUpdateDate, display: (item) => formatOracleResponseDate(item.LastUpdateDate, true) },
{ key: "actions", label: "Actions", value: () => "", display: () => "", sortable: false }
{ key: "lastUpdateDate", label: "Last Update Date", value: (item) => item.LastUpdateDate, display: (item) => formatOracleResponseDate(item.LastUpdateDate, true) }
];
}

View File

@@ -0,0 +1,113 @@
/* Keep layout rules on the outer table, never on expanded product tables. */
.opportunities-extension-table[data-opportunities-layout="inline-actions"] {
width: 100%;
min-width: 1120px;
table-layout: fixed;
}
/* Fixed table layout shares leftover width only between the two auto columns. */
.opportunities-extension-table > thead > tr > th[data-column="name"] { width: auto; }
.opportunities-extension-table > thead > tr > th[data-column="customer"] { width: auto; }
.opportunities-extension-table > thead > tr > th[data-column="owner"] { width: 132px; }
.opportunities-extension-table > thead > tr > th[data-column="optyNumber"] { width: 106px; }
.opportunities-extension-table > thead > tr > th[data-column="revenue"] { width: 124px; }
.opportunities-extension-table > thead > tr > th[data-column="closeDate"] { width: 100px; }
.opportunities-extension-table > thead > tr > th[data-column="status"] { width: 114px; }
.opportunities-extension-table > thead > tr > th[data-column="winProbability"] { width: 110px; }
.opportunities-extension-table > thead > tr > th[data-column="stage"] { width: 94px; }
.opportunities-extension-table > thead > tr > th[data-column="lastUpdateDate"] { width: 136px; }
.opportunities-extension-table > tbody > tr > td[data-column] {
padding: 10px 8px;
overflow: visible;
text-overflow: clip;
white-space: normal;
font-variant-numeric: tabular-nums;
}
.opportunities-extension-table > tbody > tr > td[data-column="name"],
.opportunities-extension-table > tbody > tr > td[data-column="customer"] {
position: relative;
padding-right: 16px;
padding-left: 12px;
padding-bottom: 38px;
vertical-align: top;
}
.opportunities-extension-table > tbody > tr > td[data-column="owner"] {
padding-right: 16px;
}
.opportunities-extension-table > tbody > tr > td[data-column="closeDate"],
.opportunities-extension-table > tbody > tr > td[data-column="lastUpdateDate"],
.opportunities-extension-table > tbody > tr > td[data-column="status"],
.opportunities-extension-table > tbody > tr > td[data-column="stage"],
.opportunities-extension-table > tbody > tr > td[data-column="winProbability"] {
white-space: nowrap;
}
.opportunities-extension-cell-content {
display: block;
min-width: 0;
min-height: 2.7em;
line-height: 1.35;
}
.opportunities-extension-cell-content > :first-child {
display: block;
min-width: 0;
overflow-wrap: anywhere;
}
.opportunities-extension-cell-actions {
position: absolute;
left: 12px;
right: 16px;
bottom: 10px;
display: flex;
align-items: center;
justify-content: flex-start;
gap: 6px;
height: 24px;
}
.opportunities-extension-cell-actions .opportunities-extension-action-button {
width: 24px;
height: 24px;
padding: 2px;
}
.opportunities-extension-cell-actions .opportunities-extension-action-button svg {
width: 18px;
height: 18px;
}
.opportunities-extension-cell-actions button:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
.opportunities-extension-table > thead > tr > th[data-column] .opportunities-extension-sort-button {
display: grid;
grid-template-columns: minmax(0, 1fr) 12px;
gap: 6px;
padding: 10px 8px;
align-items: center;
}
.opportunities-extension-table > thead > tr > th[data-column="name"] .opportunities-extension-sort-button,
.opportunities-extension-table > thead > tr > th[data-column="customer"] .opportunities-extension-sort-button {
padding-left: 12px;
padding-right: 16px;
}
.opportunities-extension-sort-label {
min-width: 0;
white-space: normal;
overflow-wrap: anywhere;
}
.opportunities-extension-table > thead > tr > th[data-column] .opportunities-extension-sort-button::after {
position: static;
justify-self: end;
}

View File

@@ -48,6 +48,7 @@ function createOpportunitiesTable({
}
table.textContent = "";
table.setAttribute("data-opportunities-layout", "inline-actions");
table.setAttribute("aria-busy", opportunitiesTableState.opportunitiesTableState.status === "loading" ? "true" : "false");
const caption = document.createElement("caption");
@@ -61,6 +62,7 @@ function createOpportunitiesTable({
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");
@@ -75,7 +77,10 @@ function createOpportunitiesTable({
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}` : ""}`);
sortButton.textContent = column.label;
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);
}
@@ -103,32 +108,26 @@ function createOpportunitiesTable({
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 === "actions") {
const actionsContent = document.createElement("span");
actionsContent.className = "opportunities-extension-actions-content";
const productsResult = productsContentState.opptyProductsByNumber.get(String(item.OptyNumber));
if (productsResult) {
actionsContent.append(createProductsCountButton(item.OptyNumber, productsResult));
}
actionsContent.append(createCloudConsumptionButton(item));
cell.append(actionsContent);
} 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" && item.OptyNumber) {
if (column.key === "name") {
const nameCellContent = document.createElement("span");
nameCellContent.className = "opportunities-extension-name-content";
nameCellContent.append(opportunityLink);
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");
@@ -139,12 +138,19 @@ function createOpportunitiesTable({
cell.append(opportunityLink);
}
} else if (column.key === "customer") {
cell.append(createDetailLink(
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));
customerCellContent.append(customerLink, customerActions);
cell.append(customerCellContent);
} else {
cell.textContent = displayOpportunityValue(column, item);
}