Implemented a tooltip on the SR to display the Internal SR
This commit is contained in:
40
dist/chromium/background.js
vendored
40
dist/chromium/background.js
vendored
@@ -17,6 +17,7 @@ function createMessageTypes() {
|
|||||||
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
||||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||||
|
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||||
@@ -741,6 +742,35 @@ function createSpaActionOptions({ fetchJson }) {
|
|||||||
return { requestActionTeamMembers, requestActionFindLookup, requestMgmtAction };
|
return { requestActionTeamMembers, requestActionFindLookup, requestMgmtAction };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Source: src/services/fusion/sr-details.js
|
||||||
|
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 };
|
||||||
|
}
|
||||||
|
|
||||||
// Source: src/services/spa/current-user.js
|
// Source: src/services/spa/current-user.js
|
||||||
function createSpaCurrentUser({ fetchJson }) {
|
function createSpaCurrentUser({ fetchJson }) {
|
||||||
async function requestCurrentUser() {
|
async function requestCurrentUser() {
|
||||||
@@ -1839,6 +1869,7 @@ function registerBackgroundMessages({
|
|||||||
requestActionTeamMembers,
|
requestActionTeamMembers,
|
||||||
requestActionFindLookup,
|
requestActionFindLookup,
|
||||||
requestMgmtAction,
|
requestMgmtAction,
|
||||||
|
requestInternalServiceRequest,
|
||||||
requestCurrentUser,
|
requestCurrentUser,
|
||||||
requestConsumerTokenService,
|
requestConsumerTokenService,
|
||||||
requestConsumptionTrend,
|
requestConsumptionTrend,
|
||||||
@@ -1933,10 +1964,10 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction].includes(message.type)) {
|
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction, messageTypes.requestInternalServiceRequest].includes(message.type)) {
|
||||||
const request = message.type === messageTypes.requestMgmtAction ? requestMgmtAction : message.type === messageTypes.requestActionTeamMembers ? requestActionTeamMembers : requestActionFindLookup;
|
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({
|
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 : []
|
debugRequests: Array.isArray(error.debugRequests) ? error.debugRequests : []
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
@@ -2142,8 +2173,9 @@ function createBackgroundApplication(overrides = {}) {
|
|||||||
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
||||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||||
const runtimeApi = environment.browser || environment.chrome;
|
const runtimeApi = environment.browser || environment.chrome;
|
||||||
|
const fusionSrDetails = createFusionSrDetails({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||||
function start() {
|
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 {
|
return {
|
||||||
start, contracts,
|
start, contracts,
|
||||||
|
|||||||
63
dist/chromium/content.js
vendored
63
dist/chromium/content.js
vendored
File diff suppressed because one or more lines are too long
3
dist/chromium/manifest.json
vendored
3
dist/chromium/manifest.json
vendored
@@ -9,7 +9,8 @@
|
|||||||
],
|
],
|
||||||
"host_permissions": [
|
"host_permissions": [
|
||||||
"https://eeho.fa.us2.oraclecloud.com/*",
|
"https://eeho.fa.us2.oraclecloud.com/*",
|
||||||
"https://spa.oracle.com/*"
|
"https://spa.oracle.com/*",
|
||||||
|
"https://comcipapic-oalprod.integration.ocp.oraclecloud.com/*"
|
||||||
],
|
],
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
|
|||||||
40
dist/firefox/background.js
vendored
40
dist/firefox/background.js
vendored
@@ -17,6 +17,7 @@ function createMessageTypes() {
|
|||||||
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
||||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||||
|
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||||
@@ -741,6 +742,35 @@ function createSpaActionOptions({ fetchJson }) {
|
|||||||
return { requestActionTeamMembers, requestActionFindLookup, requestMgmtAction };
|
return { requestActionTeamMembers, requestActionFindLookup, requestMgmtAction };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Source: src/services/fusion/sr-details.js
|
||||||
|
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 };
|
||||||
|
}
|
||||||
|
|
||||||
// Source: src/services/spa/current-user.js
|
// Source: src/services/spa/current-user.js
|
||||||
function createSpaCurrentUser({ fetchJson }) {
|
function createSpaCurrentUser({ fetchJson }) {
|
||||||
async function requestCurrentUser() {
|
async function requestCurrentUser() {
|
||||||
@@ -1839,6 +1869,7 @@ function registerBackgroundMessages({
|
|||||||
requestActionTeamMembers,
|
requestActionTeamMembers,
|
||||||
requestActionFindLookup,
|
requestActionFindLookup,
|
||||||
requestMgmtAction,
|
requestMgmtAction,
|
||||||
|
requestInternalServiceRequest,
|
||||||
requestCurrentUser,
|
requestCurrentUser,
|
||||||
requestConsumerTokenService,
|
requestConsumerTokenService,
|
||||||
requestConsumptionTrend,
|
requestConsumptionTrend,
|
||||||
@@ -1933,10 +1964,10 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction].includes(message.type)) {
|
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction, messageTypes.requestInternalServiceRequest].includes(message.type)) {
|
||||||
const request = message.type === messageTypes.requestMgmtAction ? requestMgmtAction : message.type === messageTypes.requestActionTeamMembers ? requestActionTeamMembers : requestActionFindLookup;
|
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({
|
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 : []
|
debugRequests: Array.isArray(error.debugRequests) ? error.debugRequests : []
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
@@ -2142,8 +2173,9 @@ function createBackgroundApplication(overrides = {}) {
|
|||||||
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
||||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||||
const runtimeApi = environment.browser || environment.chrome;
|
const runtimeApi = environment.browser || environment.chrome;
|
||||||
|
const fusionSrDetails = createFusionSrDetails({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||||
function start() {
|
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 {
|
return {
|
||||||
start, contracts,
|
start, contracts,
|
||||||
|
|||||||
63
dist/firefox/content.js
vendored
63
dist/firefox/content.js
vendored
File diff suppressed because one or more lines are too long
3
dist/firefox/manifest.json
vendored
3
dist/firefox/manifest.json
vendored
@@ -9,7 +9,8 @@
|
|||||||
],
|
],
|
||||||
"host_permissions": [
|
"host_permissions": [
|
||||||
"https://eeho.fa.us2.oraclecloud.com/*",
|
"https://eeho.fa.us2.oraclecloud.com/*",
|
||||||
"https://spa.oracle.com/*"
|
"https://spa.oracle.com/*",
|
||||||
|
"https://comcipapic-oalprod.integration.ocp.oraclecloud.com/*"
|
||||||
],
|
],
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ const baseManifest = {
|
|||||||
],
|
],
|
||||||
host_permissions: [
|
host_permissions: [
|
||||||
"https://eeho.fa.us2.oraclecloud.com/*",
|
"https://eeho.fa.us2.oraclecloud.com/*",
|
||||||
"https://spa.oracle.com/*"
|
"https://spa.oracle.com/*",
|
||||||
|
"https://comcipapic-oalprod.integration.ocp.oraclecloud.com/*"
|
||||||
],
|
],
|
||||||
content_scripts: [
|
content_scripts: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ module.exports = {
|
|||||||
"src/services/spa/customer-service-requests.js",
|
"src/services/spa/customer-service-requests.js",
|
||||||
"src/services/spa/workload-actions.js",
|
"src/services/spa/workload-actions.js",
|
||||||
"src/services/spa/action-options.js",
|
"src/services/spa/action-options.js",
|
||||||
|
"src/services/fusion/sr-details.js",
|
||||||
"src/services/spa/current-user.js",
|
"src/services/spa/current-user.js",
|
||||||
"src/services/spa/consumption.js",
|
"src/services/spa/consumption.js",
|
||||||
"src/services/spa/response-shapes.js",
|
"src/services/spa/response-shapes.js",
|
||||||
|
|||||||
@@ -125,8 +125,9 @@ function createBackgroundApplication(overrides = {}) {
|
|||||||
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
const requestRatecardByPlan = (...args) => spaConsumption.requestRatecardByPlan(...args);
|
||||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||||
const runtimeApi = environment.browser || environment.chrome;
|
const runtimeApi = environment.browser || environment.chrome;
|
||||||
|
const fusionSrDetails = createFusionSrDetails({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||||
function start() {
|
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 {
|
return {
|
||||||
start, contracts,
|
start, contracts,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ function registerBackgroundMessages({
|
|||||||
requestActionTeamMembers,
|
requestActionTeamMembers,
|
||||||
requestActionFindLookup,
|
requestActionFindLookup,
|
||||||
requestMgmtAction,
|
requestMgmtAction,
|
||||||
|
requestInternalServiceRequest,
|
||||||
requestCurrentUser,
|
requestCurrentUser,
|
||||||
requestConsumerTokenService,
|
requestConsumerTokenService,
|
||||||
requestConsumptionTrend,
|
requestConsumptionTrend,
|
||||||
@@ -105,10 +106,10 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction].includes(message.type)) {
|
if ([messageTypes.requestActionTeamMembers, messageTypes.requestActionFindLookup, messageTypes.requestMgmtAction, messageTypes.requestInternalServiceRequest].includes(message.type)) {
|
||||||
const request = message.type === messageTypes.requestMgmtAction ? requestMgmtAction : message.type === messageTypes.requestActionTeamMembers ? requestActionTeamMembers : requestActionFindLookup;
|
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({
|
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 : []
|
debugRequests: Array.isArray(error.debugRequests) ? error.debugRequests : []
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -217,6 +217,12 @@ function createContentApplication(overrides = {}) {
|
|||||||
maskToken: (...args) => debugContentLog.maskToken(...args), environment
|
maskToken: (...args) => debugContentLog.maskToken(...args), environment
|
||||||
});
|
});
|
||||||
const crmSrPopover = createCrmSrPopover({
|
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,
|
MODAL_ID: contracts.MODAL_ID,
|
||||||
createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args),
|
createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args),
|
||||||
createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment
|
createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function createDebugContentView({
|
|||||||
if (["requestWlActions", "requestActionTeamMembers", "requestActionFindLookup", "requestMgmtAction"].includes(entry.name)) return "actions";
|
if (["requestWlActions", "requestActionTeamMembers", "requestActionFindLookup", "requestMgmtAction"].includes(entry.name)) return "actions";
|
||||||
if (entry.name === "requestGenerateAiSummary") return "ai";
|
if (entry.name === "requestGenerateAiSummary") return "ai";
|
||||||
if (entry.name === "requestInstallBase") return "installBase";
|
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";
|
if (/^request(?:AccountSummary|AccountPlans|ConsumptionService|ConsumptionPlanDetail|RatecardByPlan)/.test(entry.name)) return "consumption";
|
||||||
return "other";
|
return "other";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ function createActivityFilters({ allowsCrmActivities, getSrSummary, getActionSum
|
|||||||
container.className = "opportunities-extension-badge-filters";
|
container.className = "opportunities-extension-badge-filters";
|
||||||
for (const [kind, title, options] of [
|
for (const [kind, title, options] of [
|
||||||
["sr", "Service Request", ["matched", "under4", "missing"]],
|
["sr", "Service Request", ["matched", "under4", "missing"]],
|
||||||
["actions", "Action", ["matched", "missing"]]
|
["actions", "WL Action", ["matched", "missing"]]
|
||||||
]) {
|
]) {
|
||||||
const section = environment.document.createElement("section");
|
const section = environment.document.createElement("section");
|
||||||
section.className = "opportunities-extension-activity-filter";
|
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;
|
const { document, window, setTimeout, clearTimeout } = environment;
|
||||||
let active = null;
|
let active = null;
|
||||||
let sequence = 0;
|
let sequence = 0;
|
||||||
@@ -74,6 +74,7 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
|||||||
dismiss.append(createCloseIcon());
|
dismiss.append(createCloseIcon());
|
||||||
dismiss.addEventListener("click", () => close(true));
|
dismiss.addEventListener("click", () => close(true));
|
||||||
panel.append(dismiss);
|
panel.append(dismiss);
|
||||||
|
const detailLoads = [];
|
||||||
items.forEach((item, index) => {
|
items.forEach((item, index) => {
|
||||||
const section = document.createElement("section");
|
const section = document.createElement("section");
|
||||||
const heading = document.createElement("div");
|
const heading = document.createElement("div");
|
||||||
@@ -94,6 +95,52 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
|||||||
details.className = "opportunities-extension-sr-details";
|
details.className = "opportunities-extension-sr-details";
|
||||||
details.textContent = descriptions[index];
|
details.textContent = descriptions[index];
|
||||||
section.append(heading, details);
|
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.append(section);
|
||||||
});
|
});
|
||||||
panel.addEventListener("pointerenter", () => clearTimeout(entry.timer));
|
panel.addEventListener("pointerenter", () => clearTimeout(entry.timer));
|
||||||
@@ -101,6 +148,7 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, envir
|
|||||||
panel.addEventListener("focusout", focusOut);
|
panel.addEventListener("focusout", focusOut);
|
||||||
host.append(panel);
|
host.append(panel);
|
||||||
active = entry;
|
active = entry;
|
||||||
|
detailLoads.forEach(load => load());
|
||||||
button.setAttribute("aria-expanded", "true");
|
button.setAttribute("aria-expanded", "true");
|
||||||
entry.position();
|
entry.position();
|
||||||
document.addEventListener("pointerdown", entry.outside, true);
|
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-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-popover a { color: #00677d; text-decoration: underline; }
|
||||||
.opportunities-extension-sr-details { white-space: pre-wrap; margin-top: 6px; }
|
.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 {
|
.opportunities-extension-sr-dismiss {
|
||||||
position: absolute; top: 6px; right: 6px; width: 28px; height: 28px;
|
position: absolute; top: 6px; right: 6px; width: 28px; height: 28px;
|
||||||
display: grid; place-items: center; padding: 4px; border: 0;
|
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",
|
requestActionTeamMembers: "opportunitiesExtension.requestActionTeamMembers",
|
||||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||||
|
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ test("activity badge filters precede Status, are accessible and combine without
|
|||||||
assert.equal(h.button("sr", "matched").textContent, "");
|
assert.equal(h.button("sr", "matched").textContent, "");
|
||||||
assert.equal(h.button("actions", "missing").textContent, "");
|
assert.equal(h.button("actions", "missing").textContent, "");
|
||||||
assert.equal(h.button("actions", "matched").type, "button");
|
assert.equal(h.button("actions", "matched").type, "button");
|
||||||
assert.equal(h.controls.children[1].children[0].textContent, "Action");
|
assert.equal(h.controls.children[1].children[0].textContent, "WL Action");
|
||||||
for (const value of ["matched", "missing"]) {
|
for (const value of ["matched", "missing"]) {
|
||||||
assert.equal(h.button("actions", value).textContent, "");
|
assert.equal(h.button("actions", value).textContent, "");
|
||||||
assert.ok(h.button("actions", value).title.startsWith("Whether the Action is registered in Workload Workbench.\n"));
|
assert.ok(h.button("actions", value).title.startsWith("Whether the Action is registered in Workload Workbench.\n"));
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ test("distribution contracts: manifests, execution boundaries and deterministic
|
|||||||
manifest_version: 3, name: "Opportunities Extension",
|
manifest_version: 3, name: "Opportunities Extension",
|
||||||
description: "Adiciona um atalho de Opportunities Extension nas paginas Oracle Fusion permitidas.",
|
description: "Adiciona um atalho de Opportunities Extension nas paginas Oracle Fusion permitidas.",
|
||||||
version: "1.0.2", permissions: ["cookies", "storage"],
|
version: "1.0.2", permissions: ["cookies", "storage"],
|
||||||
host_permissions: ["https://eeho.fa.us2.oraclecloud.com/*", "https://spa.oracle.com/*"],
|
host_permissions: ["https://eeho.fa.us2.oraclecloud.com/*", "https://spa.oracle.com/*", "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/*"],
|
||||||
content_scripts: [{
|
content_scripts: [{
|
||||||
matches: ["https://eeho.fa.us2.oraclecloud.com/hcmUI/faces/FuseWelcome*", "https://eeho.fa.us2.oraclecloud.com/fscmUI/faces/FuseWelcome*"],
|
matches: ["https://eeho.fa.us2.oraclecloud.com/hcmUI/faces/FuseWelcome*", "https://eeho.fa.us2.oraclecloud.com/fscmUI/faces/FuseWelcome*"],
|
||||||
js: ["content.js"], all_frames: true, run_at: "document_idle"
|
js: ["content.js"], all_frames: true, run_at: "document_idle"
|
||||||
|
|||||||
41
tests/crmSrDetails.test.cjs
Normal file
41
tests/crmSrDetails.test.cjs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
const assert = require("node:assert/strict");
|
||||||
|
const { test } = require("node:test");
|
||||||
|
const { loadBackground, response } = require("./support/characterization.cjs");
|
||||||
|
const type = "opportunitiesExtension.requestInternalServiceRequest";
|
||||||
|
for (const family of ["chrome", "firefox"]) {
|
||||||
|
test(`${family}: SR detail GET uses exact scope and Session authentication`, async () => {
|
||||||
|
const calls = [];
|
||||||
|
const children = [{ SrId: 123, SrNumber: "SR123", Title: "Synthetic" }];
|
||||||
|
const h = loadBackground({ family, fetch: async (url, options) => {
|
||||||
|
calls.push({ url, options });
|
||||||
|
return response({ items: [{ ServiceRequest_SRToInternalSR_Tgt: children }] });
|
||||||
|
} });
|
||||||
|
const result = await h.dispatch({ type, srId: "987", token: "secret-test" });
|
||||||
|
assert.equal(result.ok, true);
|
||||||
|
assert.deepEqual(result.items, children);
|
||||||
|
const url = new URL(calls[0].url);
|
||||||
|
assert.equal(url.hostname, "comcipapic-oalprod.integration.ocp.oraclecloud.com");
|
||||||
|
assert.equal(url.searchParams.get("q"), "SrId=987");
|
||||||
|
assert.equal(url.searchParams.get("onlyData"), "true");
|
||||||
|
assert.ok(url.searchParams.get("fields").includes("ServiceRequest_SRToInternalSR_Tgt:ReportedHours_c"));
|
||||||
|
assert.equal(calls[0].options.method, "GET");
|
||||||
|
assert.equal(calls[0].options.headers.Authorization, "Session");
|
||||||
|
assert.equal(calls[0].options.credentials, "include");
|
||||||
|
assert.equal(result.debugRequests[0].requestHeaders.Authorization, "Session");
|
||||||
|
assert.ok(!JSON.stringify(result).includes("secret-test"));
|
||||||
|
assert.equal(result.debugRequests[0].name, "requestInternalServiceRequest");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
test("SR details distinguish empty collections from errors and validate inputs", async () => {
|
||||||
|
for (const body of [{ items: [] }, { items: [{}] }, { items: [{ ServiceRequest_SRToInternalSR_Tgt: [] }] }]) {
|
||||||
|
const h = loadBackground({ fetch: async () => response(body) });
|
||||||
|
assert.deepEqual((await h.dispatch({ type, srId: "1" })).items, []);
|
||||||
|
}
|
||||||
|
for (const fetch of [async () => response({}, 403), async () => response({}), async () => response({ items: [{ ServiceRequest_SRToInternalSR_Tgt: {} }] })]) {
|
||||||
|
const h = loadBackground({ fetch });
|
||||||
|
assert.equal((await h.dispatch({ type, srId: "1", token: "test" })).ok, false);
|
||||||
|
}
|
||||||
|
const h = loadBackground({ fetch: () => assert.fail("Invalid input must not fetch") });
|
||||||
|
assert.equal((await h.dispatch({ type, srId: "1 OR 1=1", token: "test" })).ok, false);
|
||||||
|
assert.equal((await h.dispatch({ type })).ok, false);
|
||||||
|
});
|
||||||
@@ -1,6 +1,31 @@
|
|||||||
const assert = require("node:assert/strict");
|
const assert = require("node:assert/strict");
|
||||||
const { test } = require("node:test");
|
const { test } = require("node:test");
|
||||||
const { loadApplication } = require("./support/application.cjs");
|
const { loadApplication } = require("./support/application.cjs");
|
||||||
|
const flush = () => new Promise(resolve => setImmediate(resolve));
|
||||||
|
|
||||||
|
test("internal SR uses Session without TokenRelay or retries on 401", async () => {
|
||||||
|
const h = setup();
|
||||||
|
let renewals = 0;
|
||||||
|
const sent = [];
|
||||||
|
h.app.authSessionState.accessToken = "stale-token";
|
||||||
|
h.app.authTokenRelay.requestTokenRelay = async () => `fresh-${++renewals}`;
|
||||||
|
h.app.debugContentView.renderDebugPanel = () => {};
|
||||||
|
h.app.platformContentMessages.sendRuntimeMessage = async message => {
|
||||||
|
sent.push(message);
|
||||||
|
return { ok: false, httpStatus: 401, error: "Unauthorized" };
|
||||||
|
};
|
||||||
|
h.app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => [{ SrId: "123", SrNumber: "SR123", OpportunityName_Id_c: { OptyNumber: "OP1" } }];
|
||||||
|
await h.app.opportunityCrmServiceRequests.load("synthetic", 1);
|
||||||
|
const badge = h.app.opportunityCrmServiceRequests.createBadge("OP1");
|
||||||
|
h.modal.append(badge);
|
||||||
|
badge.listeners.pointerenter();
|
||||||
|
await flush();
|
||||||
|
assert.equal(renewals, 0);
|
||||||
|
assert.equal(sent.length, 1);
|
||||||
|
assert.equal(sent[0].token, undefined);
|
||||||
|
assert.ok(sent.every(item => item.type === "opportunitiesExtension.requestInternalServiceRequest"));
|
||||||
|
assert.ok(h.walk(h.panel()).some(node => node.textContent === "Unauthorized"));
|
||||||
|
});
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
const document = { activeElement: null, listeners: new Map() };
|
const document = { activeElement: null, listeners: new Map() };
|
||||||
@@ -104,3 +129,42 @@ test("SR popover pins on click, closes on Escape/outside/scroll/reset and remove
|
|||||||
assert.equal(panel(), undefined);
|
assert.equal(panel(), undefined);
|
||||||
assert.equal(document.listeners.size, 0);
|
assert.equal(document.listeners.size, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("SR tooltip loads nested details with copy/link and empty text, discarding stale responses", async () => {
|
||||||
|
const h = setup();
|
||||||
|
const calls = [];
|
||||||
|
h.app.authSessionState.accessToken = "crm-token";
|
||||||
|
h.app.authTokenRelay.requestTokenRelay = async () => "fresh-crm-token";
|
||||||
|
h.app.debugContentView.renderDebugPanel = () => {};
|
||||||
|
h.app.platformContentMessages.sendRuntimeMessage = message => new Promise(resolve => calls.push({ message, resolve }));
|
||||||
|
await h.app.opportunityCrmServiceRequests.load("synthetic", 1);
|
||||||
|
const badge = h.app.opportunityCrmServiceRequests.createBadge("OP1");
|
||||||
|
h.modal.append(badge);
|
||||||
|
badge.listeners.pointerenter();
|
||||||
|
await flush();
|
||||||
|
assert.equal(calls.length, 2);
|
||||||
|
assert.equal(calls[0].message.token, undefined);
|
||||||
|
assert.equal(calls[0].message.srId, "NOT-THE-URL-ID");
|
||||||
|
assert.ok(h.walk(h.panel()).some(node => node.textContent === "Loading SR details..."));
|
||||||
|
calls[0].resolve({ ok: true, items: [{ SrId: 99, SrNumber: "SR &child", Title: "<child>", ServiceNew_c: "Queue" }] });
|
||||||
|
calls[1].resolve({ ok: true, items: [] });
|
||||||
|
await flush();
|
||||||
|
const nodes = h.walk(h.panel());
|
||||||
|
const link = nodes.find(node => node.tag === "a" && node.textContent === "SR &child");
|
||||||
|
assert.equal(link.parent.children[0].textContent, "Internal SR Number:");
|
||||||
|
assert.ok(link.href.endsWith("srNumber=SR%20%26child&srId=99"));
|
||||||
|
assert.equal(link.parent.children[2].title, "Copy SR number");
|
||||||
|
assert.ok(nodes.some(node => node.textContent.includes("Service Queue: Queue")));
|
||||||
|
assert.ok(nodes.some(node => node.textContent === "No further details."));
|
||||||
|
h.app.crmSrPopover?.close();
|
||||||
|
h.app.opportunityCrmServiceRequests.reset();
|
||||||
|
badge.listeners.pointerenter();
|
||||||
|
const oldPanel = h.panel();
|
||||||
|
await flush();
|
||||||
|
h.app.opportunityCrmServiceRequests.reset();
|
||||||
|
calls[2].resolve({ ok: true, items: [{ SrNumber: "STALE" }] });
|
||||||
|
calls[3].resolve({ ok: false, error: "Forbidden" });
|
||||||
|
await flush();
|
||||||
|
assert.equal(h.panel(), undefined);
|
||||||
|
assert.ok(!h.walk(oldPanel).some(node => node.textContent === "STALE"));
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user