Implemented a tooltip on the SR to display the Internal SR
This commit is contained in:
@@ -125,8 +125,9 @@ function createBackgroundApplication(overrides = {}) {
|
||||
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||
const runtimeApi = environment.browser || environment.chrome;
|
||||
const fusionSrDetails = createFusionSrDetails({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||
function start() {
|
||||
startBackgroundApplication({ messageTypes, requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
startBackgroundApplication({ messageTypes, requestInternalServiceRequest: message => fusionSrDetails.requestInternalServiceRequest(message), requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
}
|
||||
return {
|
||||
start, contracts,
|
||||
|
||||
@@ -11,6 +11,7 @@ function registerBackgroundMessages({
|
||||
requestActionTeamMembers,
|
||||
requestActionFindLookup,
|
||||
requestMgmtAction,
|
||||
requestInternalServiceRequest,
|
||||
requestCurrentUser,
|
||||
requestConsumerTokenService,
|
||||
requestConsumptionTrend,
|
||||
@@ -105,10 +106,10 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction].includes(message.type)) {
|
||||
const request = message.type === messageTypes.requestMgmtAction ? requestMgmtAction : message.type === messageTypes.requestActionTeamMembers ? requestActionTeamMembers : requestActionFindLookup;
|
||||
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction, messageTypes.requestInternalServiceRequest].includes(message.type)) {
|
||||
const request = message.type === messageTypes.requestInternalServiceRequest ? requestInternalServiceRequest : message.type === messageTypes.requestMgmtAction ? requestMgmtAction : message.type === messageTypes.requestActionTeamMembers ? requestActionTeamMembers : requestActionFindLookup;
|
||||
request(message).then(sendResponse).catch(error => sendResponse({
|
||||
ok: false, error: error.message || "Unable to load Action options.",
|
||||
ok: false, httpStatus: error.httpStatus, error: error.message || "Unable to complete request.",
|
||||
debugRequests: Array.isArray(error.debugRequests) ? error.debugRequests : []
|
||||
}));
|
||||
return true;
|
||||
|
||||
@@ -217,6 +217,12 @@ function createContentApplication(overrides = {}) {
|
||||
maskToken: (...args) => debugContentLog.maskToken(...args), environment
|
||||
});
|
||||
const crmSrPopover = createCrmSrPopover({
|
||||
requestDetails: async srId => {
|
||||
const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestInternalServiceRequest, srId });
|
||||
debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []);
|
||||
if (!result?.ok) throw new Error(result?.error || "Unable to load SR details.");
|
||||
return result.items;
|
||||
},
|
||||
MODAL_ID: contracts.MODAL_ID,
|
||||
createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args),
|
||||
createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment
|
||||
|
||||
@@ -26,7 +26,7 @@ function createDebugContentView({
|
||||
if (["requestWlActions", "requestActionTeamMembers", "requestActionFindLookup", "requestMgmtAction"].includes(entry.name)) return "actions";
|
||||
if (entry.name === "requestGenerateAiSummary") return "ai";
|
||||
if (entry.name === "requestInstallBase") return "installBase";
|
||||
if (entry.name === "requestCustomerServiceRequest" || entry.name === "resquestCrmServiceRequest") return "serviceRequests";
|
||||
if (["requestCustomerServiceRequest", "resquestCrmServiceRequest", "requestInternalServiceRequest"].includes(entry.name)) return "serviceRequests";
|
||||
if (/^request(?:AccountSummary|AccountPlans|ConsumptionService|ConsumptionPlanDetail|RatecardByPlan)/.test(entry.name)) return "consumption";
|
||||
return "other";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ function createActivityFilters({ allowsCrmActivities, getSrSummary, getActionSum
|
||||
container.className = "opportunities-extension-badge-filters";
|
||||
for (const [kind, title, options] of [
|
||||
["sr", "Service Request", ["matched", "under4", "missing"]],
|
||||
["actions", "Action", ["matched", "missing"]]
|
||||
["actions", "WL Action", ["matched", "missing"]]
|
||||
]) {
|
||||
const section = environment.document.createElement("section");
|
||||
section.className = "opportunities-extension-activity-filter";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, environment }) {
|
||||
function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, requestDetails, environment }) {
|
||||
const { document, window, setTimeout, clearTimeout } = environment;
|
||||
let active = null;
|
||||
let sequence = 0;
|
||||
@@ -74,6 +74,7 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
||||
dismiss.append(createCloseIcon());
|
||||
dismiss.addEventListener("click", () => close(true));
|
||||
panel.append(dismiss);
|
||||
const detailLoads = [];
|
||||
items.forEach((item, index) => {
|
||||
const section = document.createElement("section");
|
||||
const heading = document.createElement("div");
|
||||
@@ -94,6 +95,52 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
||||
details.className = "opportunities-extension-sr-details";
|
||||
details.textContent = descriptions[index];
|
||||
section.append(heading, details);
|
||||
const children = document.createElement("div");
|
||||
children.className = "opportunities-extension-sr-children";
|
||||
children.setAttribute("aria-busy", "true");
|
||||
children.setAttribute("role", "status");
|
||||
children.textContent = "Loading SR details...";
|
||||
section.append(children);
|
||||
detailLoads.push(async () => {
|
||||
try {
|
||||
const records = await requestDetails(item.SrId);
|
||||
if (active !== entry || entry.panel !== panel) return;
|
||||
children.textContent = "";
|
||||
if (!records.length) children.textContent = "No further details.";
|
||||
for (const record of records) {
|
||||
const child = document.createElement("section");
|
||||
const row = document.createElement("div");
|
||||
row.className = "opportunities-extension-sr-number";
|
||||
const label = document.createElement("span");
|
||||
label.textContent = "Internal SR Number:";
|
||||
const link = document.createElement(record.SrNumber ? "a" : "span");
|
||||
link.textContent = record.SrNumber ? String(record.SrNumber) : "N/D";
|
||||
if (record.SrNumber) {
|
||||
link.href = `https://eeho.fa.us2.oraclecloud.com/fscmUI/redwood/service/ec/container/sr/edit?srNumber=${encodeURIComponent(String(record.SrNumber))}&srId=${encodeURIComponent(String(record.SrId ?? ""))}`;
|
||||
link.target = "_blank";
|
||||
link.rel = "noopener noreferrer";
|
||||
}
|
||||
row.append(label, link);
|
||||
if (record.SrNumber) row.append(createCopyButton(String(record.SrNumber), "SR number", "SR Number"));
|
||||
const body = document.createElement("div");
|
||||
body.className = "opportunities-extension-sr-details";
|
||||
body.textContent = ["Title", "OpportunityName_c", "StatusCd", "ServiceNew_c", "AccountPartyName",
|
||||
"LastUpdateDate", "SvcHealth_c", "AssigneePersonName", "OpenDate"].map(key =>
|
||||
`${key === "ServiceNew_c" ? "Service Queue" : key}: ${record[key] == null || record[key] === "" ? "N/D" : String(record[key])}`).join("\n");
|
||||
child.append(row, body);
|
||||
children.append(child);
|
||||
}
|
||||
} catch (error) {
|
||||
if (active !== entry || entry.panel !== panel) return;
|
||||
children.setAttribute("role", "alert");
|
||||
children.textContent = error.message || "Unable to load SR details.";
|
||||
} finally {
|
||||
if (active === entry && entry.panel === panel) {
|
||||
children.setAttribute("aria-busy", "false");
|
||||
entry.position();
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.append(section);
|
||||
});
|
||||
panel.addEventListener("pointerenter", () => clearTimeout(entry.timer));
|
||||
@@ -101,6 +148,7 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
||||
panel.addEventListener("focusout", focusOut);
|
||||
host.append(panel);
|
||||
active = entry;
|
||||
detailLoads.forEach(load => load());
|
||||
button.setAttribute("aria-expanded", "true");
|
||||
entry.position();
|
||||
document.addEventListener("pointerdown", entry.outside, true);
|
||||
|
||||
@@ -533,6 +533,11 @@
|
||||
.opportunities-extension-sr-number { display: flex; align-items: center; gap: 8px; padding-right: 30px; font-weight: 600; }
|
||||
.opportunities-extension-sr-popover a { color: #00677d; text-decoration: underline; }
|
||||
.opportunities-extension-sr-details { white-space: pre-wrap; margin-top: 6px; }
|
||||
.opportunities-extension-sr-children { margin: 10px 0 0 8px; padding-left: 10px; border-left: 2px solid #8c969a; overflow-wrap: anywhere; }
|
||||
.opportunities-extension-sr-children[aria-busy="true"] { min-height: 28px; animation: opportunities-action-options-loading 1s ease-in-out infinite alternate; }
|
||||
.opportunities-extension-sr-children[role="alert"] { color: #a12d27; }
|
||||
.opportunities-extension-modal[data-theme="dark"] .opportunities-extension-sr-children[role="alert"] { color: #ffd9d5; }
|
||||
@media (prefers-reduced-motion: reduce) { .opportunities-extension-sr-children[aria-busy="true"] { animation: none; } }
|
||||
.opportunities-extension-sr-dismiss {
|
||||
position: absolute; top: 6px; right: 6px; width: 28px; height: 28px;
|
||||
display: grid; place-items: center; padding: 4px; border: 0;
|
||||
|
||||
27
src/services/fusion/sr-details.js
Normal file
27
src/services/fusion/sr-details.js
Normal file
@@ -0,0 +1,27 @@
|
||||
function createFusionSrDetails({ fetchJson }) {
|
||||
async function requestInternalServiceRequest(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const id = String(message.srId ?? "");
|
||||
if (!/^\d+$/.test(id)) throw new Error("A numeric SrId is required.");
|
||||
const fields = "Title,SrNumber,SrId,OpportunityName_c,QueueManagers_c,StatusCd,resourceMembers;ServiceRequest_SRToInternalSR_Tgt:ReportedHours_c,Title,OpportunityName_c,StatusCd,SrNumber,ServiceNew_c,AccountPartyName,LastUpdateDate,SvcHealth_c,AssigneePersonName,OpenDate,SrId";
|
||||
const url = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_SR_management/live;profile=PROD/services/auth/1.1/proxy/oalsetCRMRestAPI/uri/https/eeho.fa.us2.oraclecloud.com/crmRestApi/resources/latest/serviceRequests"
|
||||
+ `?fields=${encodeURIComponent(fields)}&onlyData=true&q=${encodeURIComponent(`SrId=${id}`)}`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include",
|
||||
headers: { Accept: "application/json", Authorization: "Session" }
|
||||
}, "requestInternalServiceRequest", debugRequests);
|
||||
if (!Array.isArray(result?.items)) throw new Error("Invalid SR details response.");
|
||||
const items = result.items.flatMap(item => {
|
||||
const children = item.ServiceRequest_SRToInternalSR_Tgt;
|
||||
if (children == null) return [];
|
||||
if (!Array.isArray(children) || children.some(child => !child || typeof child !== "object")) throw new Error("Invalid linked SR collection.");
|
||||
return children;
|
||||
});
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) {
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return { requestInternalServiceRequest };
|
||||
}
|
||||
@@ -14,6 +14,7 @@ function createMessageTypes() {
|
||||
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||
|
||||
Reference in New Issue
Block a user