Partially implemented the Manage Time functionality
This commit is contained in:
191
dist/chromium/background.js
vendored
191
dist/chromium/background.js
vendored
@@ -1,9 +1,112 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
// Source: src/shared/time-dates.js
|
||||
function createTimeDates() {
|
||||
const months = "JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC".split(" ");
|
||||
function parse(value) {
|
||||
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(value));
|
||||
if (!match) return null;
|
||||
const date = new Date(`${value}T00:00:00.000Z`);
|
||||
return Number.isFinite(date.getTime()) && date.toISOString().slice(0, 10) === value ? date : null;
|
||||
}
|
||||
function fromApi(value) {
|
||||
const match = /^(\d{2})-([A-Z]{3})-(\d{4})$/.exec(String(value));
|
||||
if (!match) return null;
|
||||
const month = months.indexOf(match[2]) + 1;
|
||||
return parse(`${match[3]}-${String(month).padStart(2, "0")}-${match[1]}`);
|
||||
}
|
||||
function toApi(value) {
|
||||
const date = parse(value);
|
||||
if (!date) throw new Error("Select a valid reference date.");
|
||||
return `${String(date.getUTCDate()).padStart(2, "0")}-${months[date.getUTCMonth()]}-${date.getUTCFullYear()}`;
|
||||
}
|
||||
function shift(value, days) {
|
||||
const date = parse(value);
|
||||
if (!date) return value;
|
||||
date.setUTCDate(date.getUTCDate() + days);
|
||||
return date.toISOString().slice(0, 10);
|
||||
}
|
||||
function today() {
|
||||
const date = new Date();
|
||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
||||
}
|
||||
return { parse, fromApi, toApi, shift, today };
|
||||
}
|
||||
|
||||
// Source: src/services/fusion/time-entries.js
|
||||
function createTimeEntries({ fetchJson, dates, getResourceUser }) {
|
||||
const endpoint = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/oalset_timeentrymobile/live;profile=PROD/services/auth/1.1/proxy/oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/mgmt/timeEntries/weekDetails";
|
||||
async function requestWeekDetails(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const date = dates.toApi(message.dateReference);
|
||||
const items = await fetchJson(`${endpoint}?dateValue=${encodeURIComponent(date)}`, {
|
||||
method: "GET", credentials: "include", headers: { Authorization: "Session", Accept: "application/json" }
|
||||
}, "requestWeekDetails", debugRequests);
|
||||
if (!Array.isArray(items) || items.length !== 7 || items.some(item => !dates.fromApi(item?.Date) || !dates.fromApi(item?.EndDate))
|
||||
|| new Set(items.map(item => item.Date)).size !== 7) throw new Error("Invalid week details response.");
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) {
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async function requestActiveServiceRequests(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
if (!/^\d+$/.test(String(message.weekId)) || Number(message.weekId) <= 0) throw new Error("Missing or invalid WeekId.");
|
||||
const resource = await getResourceUser(message);
|
||||
debugRequests.push(...resource.debugRequests);
|
||||
const url = endpoint.replace(/weekDetails$/, "activeServiceRequests") + `?resourceId=${encodeURIComponent(resource.resource.resourcePartyId)}&weekId=${encodeURIComponent(message.weekId)}`;
|
||||
const items = await fetchJson(url, { method: "GET", credentials: "include", headers: { Authorization: "Session", Accept: "application/json" } }, "requestActiveServiceRequests", debugRequests);
|
||||
if (!Array.isArray(items)) throw new Error("Invalid active Service Requests response.");
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) { error.debugRequests = [...debugRequests, ...(error.debugRequests || [])]; throw error; }
|
||||
}
|
||||
async function requestServiceRequestExpand(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
if (!Array.isArray(message.srNumbers)) throw new Error("Missing Service Request numbers.");
|
||||
const numbers = [...new Set(message.srNumbers.map(value => String(value || "").trim()).filter(Boolean))].filter(value => value !== "non-service-sr");
|
||||
if (numbers.some(value => !/^SR\d+$/.test(value))) throw new Error("Invalid Service Request number.");
|
||||
const batches = [];
|
||||
for (let index = 0; index < numbers.length; index += 50) batches.push(numbers.slice(index, index + 50));
|
||||
if (!batches.length || batches[batches.length - 1].length === 50) batches.push([]);
|
||||
batches[batches.length - 1].push("non-service-sr");
|
||||
const base = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/oalset_timeentrymobile/live;profile=PROD/services/auth/1.1/proxy/crmRestApiSearchResourcesLatestCustomActions/uri/https/eeho.fa.us2.oraclecloud.com/crmRestApi/resources/latest/serviceRequests";
|
||||
const fields = "SrNumber,SRActivities_c,ProblemDescription,AccountPartyUniqueName,ServiceNew_c,OptyOwner_c,OptyName_c,OptyNumber_c,ReportedByPartyUniqueName,StatusCdMeaning,CountryText_c,AssigneePersonName,OptyStatus_c";
|
||||
const items = [];
|
||||
for (const batch of batches) {
|
||||
const query = `SrNumber in (${batch.map(value => `'${value}'`).join(",")})`;
|
||||
const url = `${base}?expand=ServiceRequest_SRToInternalSR_Tgt&fields=${encodeURIComponent(fields)}&limit=200&onlyData=true&q=${encodeURIComponent(query).replace(/'/g, "%27")}`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include", headers: { Authorization: "Session", Accept: "application/json", "vb-proxy-header-rest-framework-version": "3" } }, "requestServiceRequestExpand", debugRequests);
|
||||
if (!Array.isArray(result?.items)) throw new Error("Invalid Service Request expansion response.");
|
||||
items.push(...result.items);
|
||||
}
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
async function requestLookupTaskType() {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const url = endpoint.replace(/mgmt\/timeEntries\/weekDetails$/, "crm/lookups?lookupType=SCTA_TASK_TYPE&type=CUSTOM");
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include", headers: { Authorization: "Session", Accept: "application/json" } }, "requestLookupTaskType", debugRequests);
|
||||
if (!Array.isArray(result?.items)) throw new Error("Invalid Task Type lookup response.");
|
||||
return { ok: true, items: result.items, debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
return { requestWeekDetails, requestActiveServiceRequests, requestServiceRequestExpand, requestLookupTaskType };
|
||||
}
|
||||
|
||||
// Source: src/shared/messages.js
|
||||
/** Stable wire names. All payloads remain plain, serializable objects. */
|
||||
function createMessageTypes() {
|
||||
return Object.freeze({
|
||||
requestWeekDetails: "opportunitiesExtension.requestWeekDetails",
|
||||
requestLookupTaskType: "opportunitiesExtension.requestLookupTaskType",
|
||||
requestServiceRequestExpand: "opportunitiesExtension.requestServiceRequestExpand",
|
||||
requestResourceUser: "opportunitiesExtension.requestResourceUser",
|
||||
requestActiveServiceRequests: "opportunitiesExtension.requestActiveServiceRequests",
|
||||
getXsrfToken: "opportunitiesExtension.getXsrfToken",
|
||||
refreshXsrfCookie: "opportunitiesExtension.refreshXsrfCookie",
|
||||
requestOpptyProducts: "opportunitiesExtension.requestOpptyProducts",
|
||||
@@ -1056,7 +1159,10 @@ function createFusionSrDetails({ fetchJson, tabsCreate, tabsRemove, supportsFire
|
||||
}
|
||||
|
||||
// Source: src/services/fusion/sr-create.js
|
||||
function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, internalServiceRequestHeaders }) {
|
||||
function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, internalServiceRequestHeaders, runtimeApi }) {
|
||||
const resourceRequests = new Map();
|
||||
let resourceGeneration = 0;
|
||||
const resourceCacheKey = "opportunitiesExtension.resourceUsers.v1";
|
||||
const base = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/";
|
||||
const catalog = base + "crmRestApiResources/uri/https/eeho.fa.us2.oraclecloud.com/crmRestApi/resources/11.13.18.05/Catalogue_c";
|
||||
const resourceUsers = base + "oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/crm/resourceUsers";
|
||||
@@ -1082,12 +1188,45 @@ function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, in
|
||||
dateOnly(payload.CustomerDeadline_c, "Customer deadline");
|
||||
return { ...payload, SvcQuestionsCollection_c: [], SourceCd: "SVC_OPPORTUNITY_SCREEN", SeverityCd: "ORA_SVC_SEV2", ChannelTypeCd: "ORA_SVC_WEB" };
|
||||
}
|
||||
async function requestResourceUser(email, debugRequests) {
|
||||
const emailAddress = text(email, "current user email");
|
||||
const resource = await fetchJson(`${resourceUsers}?emailAddress=${encodeURIComponent(emailAddress)}`, {
|
||||
method: "GET", credentials: "include", headers: { Accept: "application/json", Authorization: "Session" }
|
||||
}, "requestResourceUser", debugRequests);
|
||||
return numericId(resource?.resourcePartyId, "resourcePartyId");
|
||||
async function requestResourceUser(message, debugRequests) {
|
||||
try {
|
||||
const result = await getResourceUser(message);
|
||||
debugRequests.push(...result.debugRequests);
|
||||
return numericId(result.resource.resourcePartyId, "resourcePartyId");
|
||||
} catch (error) { debugRequests.push(...(error.debugRequests || [])); throw error; }
|
||||
}
|
||||
async function getResourceUser(message) {
|
||||
const emailAddress = text(message.emailAddress, "current user email").toLowerCase();
|
||||
const duration = Number(message.cacheMaxAgeMs) > 0 ? Math.min(Number(message.cacheMaxAgeMs), 168 * 3600000) : 24 * 3600000;
|
||||
const fresh = timestamp => Number.isFinite(timestamp) && Date.now() >= timestamp && Date.now() - timestamp < duration;
|
||||
const current = resourceRequests.get(emailAddress);
|
||||
if (current && (current.fetchedAt === null || fresh(current.fetchedAt))) return { ok: true, resource: await current.promise, debugRequests: [] };
|
||||
const generation = resourceGeneration;
|
||||
const record = { promise: null, fetchedAt: null };
|
||||
const debugRequests = [];
|
||||
const pending = (async () => {
|
||||
try {
|
||||
const stored = await runtimeApi?.storage?.session?.get(resourceCacheKey);
|
||||
const cached = stored?.[resourceCacheKey];
|
||||
if (cached?.emailAddress === emailAddress && cached.resource?.resourcePartyId && fresh(cached.fetchedAt)) {
|
||||
record.fetchedAt = cached.fetchedAt;
|
||||
return cached.resource;
|
||||
}
|
||||
} catch { /* Session storage is optional; retain the in-memory cache. */ }
|
||||
const resource = await fetchJson(`${resourceUsers}?emailAddress=${encodeURIComponent(emailAddress)}`, {
|
||||
method: "GET", credentials: "include", headers: { Accept: "application/json", Authorization: "Session" }
|
||||
}, "requestResourceUser", debugRequests);
|
||||
numericId(resource?.resourcePartyId, "resourcePartyId");
|
||||
record.fetchedAt = Date.now();
|
||||
if (generation === resourceGeneration) {
|
||||
try { await runtimeApi?.storage?.session?.set({ [resourceCacheKey]: { emailAddress, resource, fetchedAt: record.fetchedAt } }); } catch { /* Keep the successful response in memory. */ }
|
||||
}
|
||||
return resource;
|
||||
})();
|
||||
record.promise = pending;
|
||||
resourceRequests.set(emailAddress, record);
|
||||
try { return { ok: true, resource: await pending, debugRequests }; }
|
||||
catch (error) { if (resourceRequests.get(emailAddress) === record) resourceRequests.delete(emailAddress); error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
async function requestPostInternalServiceRequest(message) {
|
||||
const debugRequests = [];
|
||||
@@ -1108,7 +1247,7 @@ function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, in
|
||||
for (const name of ["AccountPartyId", "OpportunityName_Id_c"]) payload[name] = numericId(parent[name], name);
|
||||
for (const name of ["OpportunityName_c", "RegionText_c", "SvcHealth_c", "Language_c", "CountryText_c", "PrimaryPillarNew_c"]) payload[name] = text(parent[name], name);
|
||||
payload.SecondaryPillarNew_c = parent.SecondaryPillarNew_c == null ? null : text(parent.SecondaryPillarNew_c, "SecondaryPillarNew_c");
|
||||
payload.ReportedByPartyId = await requestResourceUser(message.emailAddress, debugRequests);
|
||||
payload.ReportedByPartyId = await requestResourceUser(message, debugRequests);
|
||||
const url = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_SR_management/live;profile=PROD/services/auth/1.1/proxy/oalsetCRMRestAPICloudAccount/uri/https/eeho.fa.us2.oraclecloud.com/crmRestApi/resources/latest/serviceRequests";
|
||||
const result = await fetchJson(url, { method: "POST", credentials: "include",
|
||||
headers: await internalServiceRequestHeaders(url),
|
||||
@@ -1138,7 +1277,7 @@ function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, in
|
||||
if (message.phase !== "prepare" && message.phase !== "confirm") throw new Error("Service Request confirmation is required.");
|
||||
const payload = payloadFor(message.payload);
|
||||
if (message.phase === "prepare") {
|
||||
payload.ReportedByPartyId = await requestResourceUser(message.emailAddress, debugRequests);
|
||||
payload.ReportedByPartyId = await requestResourceUser(message, debugRequests);
|
||||
const sharedHeaders = await previewTokenHeaders(catalog);
|
||||
return { ok: true, payload, debugRequests, headers: {
|
||||
requestSrTokenCatalog: sharedHeaders,
|
||||
@@ -1194,7 +1333,12 @@ function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, in
|
||||
}
|
||||
}
|
||||
}
|
||||
return { requestPostServiceRequest, requestPostInternalServiceRequest };
|
||||
async function invalidateResourceUser() {
|
||||
resourceGeneration++;
|
||||
resourceRequests.clear();
|
||||
await runtimeApi?.storage?.session?.set({ [resourceCacheKey]: null });
|
||||
}
|
||||
return { requestPostServiceRequest, requestPostInternalServiceRequest, getResourceUser, invalidateResourceUser };
|
||||
}
|
||||
|
||||
// Source: src/services/spa/current-user.js
|
||||
@@ -2280,7 +2424,13 @@ function startBackgroundApplication(dependencies) {
|
||||
/** Register synchronously; replies retain the WebExtension sendResponse contract. */
|
||||
function registerBackgroundMessages({
|
||||
messageTypes,
|
||||
requestWeekDetails,
|
||||
requestLookupTaskType,
|
||||
requestServiceRequestExpand,
|
||||
requestResourceUser,
|
||||
requestActiveServiceRequests,
|
||||
invalidateProductsCache,
|
||||
invalidateResourceUser = async () => {},
|
||||
getXsrfTokenCookie,
|
||||
refreshXsrfCookie,
|
||||
requestAccountPlans,
|
||||
@@ -2313,6 +2463,17 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (!message || !message.type) {
|
||||
return false;
|
||||
}
|
||||
if (message.type === messageTypes.requestLookupTaskType) {
|
||||
requestLookupTaskType().then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
error: error.message, httpStatus: error.httpStatus, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
if ([messageTypes.requestServiceRequestExpand, messageTypes.requestWeekDetails, messageTypes.requestResourceUser, messageTypes.requestActiveServiceRequests].includes(message.type)) {
|
||||
const request = message.type === messageTypes.requestServiceRequestExpand ? requestServiceRequestExpand : message.type === messageTypes.requestWeekDetails ? requestWeekDetails : message.type === messageTypes.requestResourceUser ? requestResourceUser : requestActiveServiceRequests;
|
||||
request(message).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
error: error.message, httpStatus: error.httpStatus, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
if (message.type === messageTypes.requestPostInternalServiceRequest) {
|
||||
requestPostInternalServiceRequest(message).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
error: error.message, debugRequests: error.debugRequests || [] }));
|
||||
@@ -2343,7 +2504,7 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
}
|
||||
|
||||
if (message.type === messageTypes.invalidateProductsCache) {
|
||||
invalidateProductsCache().then(() => sendResponse({ ok: true })).catch(error => sendResponse({ ok: false, error: error.message || "Unable to clear products cache." }));
|
||||
invalidateProductsCache().then(() => invalidateResourceUser()).then(() => sendResponse({ ok: true })).catch(error => sendResponse({ ok: false, error: error.message || "Unable to clear products cache." }));
|
||||
return true;
|
||||
}
|
||||
if (message.type === messageTypes.getXsrfToken) {
|
||||
@@ -2514,6 +2675,7 @@ function createBackgroundApplication(overrides = {}) {
|
||||
...overrides
|
||||
};
|
||||
const messageTypes = createMessageTypes();
|
||||
const timeEntries = createTimeEntries({ dates: createTimeDates(), fetchJson: (...args) => httpBackgroundJson.fetchJson(...args), getResourceUser: message => fusionSrCreate.getResourceUser(message) });
|
||||
const spaCurrentUser = createSpaCurrentUser({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||
const requestCurrentUser = () => spaCurrentUser.requestCurrentUser();
|
||||
const contracts = createBackgroundContracts();
|
||||
@@ -2634,6 +2796,7 @@ function createBackgroundApplication(overrides = {}) {
|
||||
const runtimeApi = environment.browser || environment.chrome;
|
||||
const srRequestHeaders = createSrRequestHeaders({ runtimeApi });
|
||||
const fusionSrCreate = createFusionSrCreate({
|
||||
runtimeApi,
|
||||
fetchJson: (...args) => httpBackgroundJson.fetchJson(...args),
|
||||
tokenHeaders: (...args) => srRequestHeaders.tokenHeaders(...args),
|
||||
internalServiceRequestHeaders: url => srRequestHeaders.internalServiceRequestHeaders(url),
|
||||
@@ -2651,6 +2814,12 @@ function createBackgroundApplication(overrides = {}) {
|
||||
function start() {
|
||||
srRequestHeaders.start();
|
||||
startBackgroundApplication({
|
||||
invalidateResourceUser: () => fusionSrCreate.invalidateResourceUser(),
|
||||
requestWeekDetails: message => timeEntries.requestWeekDetails(message),
|
||||
requestLookupTaskType: () => timeEntries.requestLookupTaskType(),
|
||||
requestServiceRequestExpand: message => timeEntries.requestServiceRequestExpand(message),
|
||||
requestResourceUser: message => fusionSrCreate.getResourceUser(message),
|
||||
requestActiveServiceRequests: message => timeEntries.requestActiveServiceRequests(message),
|
||||
requestLookupTypePlatform: () => fusionSrDetails.requestLookupTypePlatform(),
|
||||
requestPostInternalServiceRequest: message => fusionSrCreate.requestPostInternalServiceRequest(message),
|
||||
requestInternalSrServices: message => fusionSrDetails.requestInternalSrServices(message),
|
||||
|
||||
Reference in New Issue
Block a user