Updated the Service Requests badge to display the hours logged on the SR
This commit is contained in:
8
dist/chromium/content.js
vendored
8
dist/chromium/content.js
vendored
@@ -1999,7 +1999,13 @@ function createOpportunityCrmServiceRequests({ requestCrmServiceRequest, isCurre
|
|||||||
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
||||||
badge.className = "opportunities-extension-crm-sr-badge";
|
badge.className = "opportunities-extension-crm-sr-badge";
|
||||||
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
||||||
badge.textContent = status === "error" ? "SR ?" : items.length ? "\u2705 SR" : "\u26d4 SR";
|
const hours = items.map(item => item.ReportedHours_c).filter(value =>
|
||||||
|
(typeof value === "number" || (typeof value === "string" && value.trim() !== "")) && Number.isFinite(Number(value))
|
||||||
|
).map(Number);
|
||||||
|
const reportedHours = hours.length === items.length
|
||||||
|
? new Intl.NumberFormat("en-US", { useGrouping: false, maximumFractionDigits: 10 }).format(hours.reduce((total, value) => total + value, 0))
|
||||||
|
: "N/D";
|
||||||
|
badge.textContent = status === "error" ? "SR ?" : items.length ? `\u2705 SR (${reportedHours}${reportedHours === "N/D" ? "" : "h"})` : "\u26d4 SR";
|
||||||
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
||||||
const descriptions = items.map(item => [
|
const descriptions = items.map(item => [
|
||||||
`Title: ${display(item.Title)}`,
|
`Title: ${display(item.Title)}`,
|
||||||
|
|||||||
8
dist/firefox/content.js
vendored
8
dist/firefox/content.js
vendored
@@ -1999,7 +1999,13 @@ function createOpportunityCrmServiceRequests({ requestCrmServiceRequest, isCurre
|
|||||||
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
||||||
badge.className = "opportunities-extension-crm-sr-badge";
|
badge.className = "opportunities-extension-crm-sr-badge";
|
||||||
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
||||||
badge.textContent = status === "error" ? "SR ?" : items.length ? "\u2705 SR" : "\u26d4 SR";
|
const hours = items.map(item => item.ReportedHours_c).filter(value =>
|
||||||
|
(typeof value === "number" || (typeof value === "string" && value.trim() !== "")) && Number.isFinite(Number(value))
|
||||||
|
).map(Number);
|
||||||
|
const reportedHours = hours.length === items.length
|
||||||
|
? new Intl.NumberFormat("en-US", { useGrouping: false, maximumFractionDigits: 10 }).format(hours.reduce((total, value) => total + value, 0))
|
||||||
|
: "N/D";
|
||||||
|
badge.textContent = status === "error" ? "SR ?" : items.length ? `\u2705 SR (${reportedHours}${reportedHours === "N/D" ? "" : "h"})` : "\u26d4 SR";
|
||||||
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
||||||
const descriptions = items.map(item => [
|
const descriptions = items.map(item => [
|
||||||
`Title: ${display(item.Title)}`,
|
`Title: ${display(item.Title)}`,
|
||||||
|
|||||||
@@ -35,7 +35,13 @@ function createOpportunityCrmServiceRequests({ requestCrmServiceRequest, isCurre
|
|||||||
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
const badge = environment.document.createElement(items.length && status === "ready" ? "button" : "span");
|
||||||
badge.className = "opportunities-extension-crm-sr-badge";
|
badge.className = "opportunities-extension-crm-sr-badge";
|
||||||
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
badge.setAttribute("data-state", status === "error" ? "error" : items.length ? "matched" : "missing");
|
||||||
badge.textContent = status === "error" ? "SR ?" : items.length ? "\u2705 SR" : "\u26d4 SR";
|
const hours = items.map(item => item.ReportedHours_c).filter(value =>
|
||||||
|
(typeof value === "number" || (typeof value === "string" && value.trim() !== "")) && Number.isFinite(Number(value))
|
||||||
|
).map(Number);
|
||||||
|
const reportedHours = hours.length === items.length
|
||||||
|
? new Intl.NumberFormat("en-US", { useGrouping: false, maximumFractionDigits: 10 }).format(hours.reduce((total, value) => total + value, 0))
|
||||||
|
: "N/D";
|
||||||
|
badge.textContent = status === "error" ? "SR ?" : items.length ? `\u2705 SR (${reportedHours}${reportedHours === "N/D" ? "" : "h"})` : "\u26d4 SR";
|
||||||
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
const display = value => value === null || value === undefined || value === "" ? "N/D" : String(value);
|
||||||
const descriptions = items.map(item => [
|
const descriptions = items.map(item => [
|
||||||
`Title: ${display(item.Title)}`,
|
`Title: ${display(item.Title)}`,
|
||||||
|
|||||||
@@ -14,6 +14,15 @@ const sr = (number, id = "SR-1") => ({ SrNumber: id, Title: "<script>synthetic</
|
|||||||
OpportunityName_Id_c: { OptyNumber: number }, Owner: { PersonFirstName: "Test", PersonLastName: "Owner",
|
OpportunityName_Id_c: { OptyNumber: number }, Owner: { PersonFirstName: "Test", PersonLastName: "Owner",
|
||||||
PrimaryEmail: { EmailAddress: "test@example.invalid" } }, DoNotCallFlag: false });
|
PrimaryEmail: { EmailAddress: "test@example.invalid" } }, DoNotCallFlag: false });
|
||||||
|
|
||||||
|
test("SR badge shows reported hours, sums linked SRs and preserves missing values", async () => {
|
||||||
|
for (const [values, expected] of [[[4], "4h"], [[0], "0h"], [[2, "1.5"], "3.5h"], [[0.1, 0.2], "0.3h"], [[null], "N/D"], [[4, null], "N/D"], [[""], "N/D"], [["invalid"], "N/D"]]) {
|
||||||
|
const app = setup(async () => response({ items: values.map((value, index) => ({ ...sr("A", `SR-${index}`), ReportedHours_c: value })), hasMore: false }));
|
||||||
|
await app.opportunityCrmServiceRequests.load("synthetic", 1);
|
||||||
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("A").textContent, `\u2705 SR (${expected})`);
|
||||||
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("OTHER").textContent, "\u26d4 SR");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("CRM fetch is called without the environment object as its receiver", async () => {
|
test("CRM fetch is called without the environment object as its receiver", async () => {
|
||||||
let calls = 0;
|
let calls = 0;
|
||||||
const app = setup(async function (url, options) {
|
const app = setup(async function (url, options) {
|
||||||
@@ -79,7 +88,7 @@ test("CRM query preserves payload, paginates before opportunities, uses tokenrel
|
|||||||
assert.equal(app.debugContentView.getRequestCategory(log), "serviceRequests");
|
assert.equal(app.debugContentView.getRequestCategory(log), "serviceRequests");
|
||||||
}
|
}
|
||||||
const found = app.opportunityCrmServiceRequests.createBadge("TEST-1");
|
const found = app.opportunityCrmServiceRequests.createBadge("TEST-1");
|
||||||
assert.equal(found.textContent, "\u2705 SR");
|
assert.equal(found.textContent, "\u2705 SR (0h)");
|
||||||
assert.equal(found.attributes["data-state"], "matched");
|
assert.equal(found.attributes["data-state"], "matched");
|
||||||
for (const detail of ["SR-0", "SR-1", "Reported Hours: 0", "Test Owner", "test@example.invalid", "<script>synthetic</script>"])
|
for (const detail of ["SR-0", "SR-1", "Reported Hours: 0", "Test Owner", "test@example.invalid", "<script>synthetic</script>"])
|
||||||
assert.ok(found.attributes["aria-label"].includes(detail));
|
assert.ok(found.attributes["aria-label"].includes(detail));
|
||||||
@@ -122,7 +131,7 @@ test("stale CRM results cannot overwrite a reopened modal or continue pagination
|
|||||||
await app.opportunityCrmServiceRequests.load("token", 2);
|
await app.opportunityCrmServiceRequests.load("token", 2);
|
||||||
resolveOld(response({ items: [sr("OLD")], hasMore: true, count: 1, offset: 0 }));
|
resolveOld(response({ items: [sr("OLD")], hasMore: true, count: 1, offset: 0 }));
|
||||||
await old;
|
await old;
|
||||||
assert.equal(app.opportunityCrmServiceRequests.createBadge("NEW").textContent, "\u2705 SR");
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("NEW").textContent, "\u2705 SR (0h)");
|
||||||
assert.equal(app.opportunityCrmServiceRequests.createBadge("OLD").textContent, "\u26d4 SR");
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("OLD").textContent, "\u26d4 SR");
|
||||||
assert.equal(app.debugState.requestLog.length, 1);
|
assert.equal(app.debugState.requestLog.length, 1);
|
||||||
});
|
});
|
||||||
@@ -144,8 +153,8 @@ test("Reference changes share pending pagination and reuse completed CRM results
|
|||||||
app.opportunitiesQueryState.periodRequestVersion = 3;
|
app.opportunitiesQueryState.periodRequestVersion = 3;
|
||||||
await app.opportunityCrmServiceRequests.load("token", 3);
|
await app.opportunityCrmServiceRequests.load("token", 3);
|
||||||
assert.equal(calls, 2);
|
assert.equal(calls, 2);
|
||||||
assert.equal(app.opportunityCrmServiceRequests.createBadge("A").textContent, "\u2705 SR");
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("A").textContent, "\u2705 SR (0h)");
|
||||||
assert.equal(app.opportunityCrmServiceRequests.createBadge("B").textContent, "\u2705 SR");
|
assert.equal(app.opportunityCrmServiceRequests.createBadge("B").textContent, "\u2705 SR (0h)");
|
||||||
app.opportunityCrmServiceRequests.reset();
|
app.opportunityCrmServiceRequests.reset();
|
||||||
await app.opportunityCrmServiceRequests.load("token", 3);
|
await app.opportunityCrmServiceRequests.load("token", 3);
|
||||||
assert.equal(calls, 3);
|
assert.equal(calls, 3);
|
||||||
|
|||||||
@@ -124,11 +124,11 @@ test("CRM SR badge follows Ramp Months and remains visible while product data is
|
|||||||
}];
|
}];
|
||||||
await h.app.opportunityCrmServiceRequests.load("synthetic", h.app.opportunitiesQueryState.periodRequestVersion);
|
await h.app.opportunityCrmServiceRequests.load("synthetic", h.app.opportunitiesQueryState.periodRequestVersion);
|
||||||
h.app.opportunitiesTable.renderOpportunitiesTable();
|
h.app.opportunitiesTable.renderOpportunitiesTable();
|
||||||
assert.equal(findClass(h.cell("name"), "opportunities-extension-crm-sr-badge").textContent, "\u2705 SR");
|
assert.equal(findClass(h.cell("name"), "opportunities-extension-crm-sr-badge").textContent, "\u2705 SR (0h)");
|
||||||
h.app.productsContentState.opptyProductsByNumber.set("TEST-1", { items: [{ RampMonths_c: 3 }] });
|
h.app.productsContentState.opptyProductsByNumber.set("TEST-1", { items: [{ RampMonths_c: 3 }] });
|
||||||
h.app.opportunitiesTable.renderOpportunitiesTable();
|
h.app.opportunitiesTable.renderOpportunitiesTable();
|
||||||
const actions = h.cell("name").children[0].children[1];
|
const actions = h.cell("name").children[0].children[1];
|
||||||
assert.deepEqual(actions.children.map(child => child.textContent), ["1", "RM 3", "\u2705 SR", "Act ?"]);
|
assert.deepEqual(actions.children.map(child => child.textContent), ["1", "RM 3", "\u2705 SR (0h)", "Act ?"]);
|
||||||
findClass(h.cell("name"), "opportunities-extension-products-count").click();
|
findClass(h.cell("name"), "opportunities-extension-products-count").click();
|
||||||
assert.ok(findClass(h.rows()[1], "opportunities-extension-products-table"));
|
assert.ok(findClass(h.rows()[1], "opportunities-extension-products-table"));
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user