Implemented the Organization Chart feature to create customer organizational

This commit is contained in:
2026-10-26 18:15:32 -03:00
parent bf48ed1dcb
commit 3229ce9c41
41 changed files with 4099 additions and 63 deletions

View File

@@ -7,7 +7,7 @@
OptyNumber: `TEST${index + 1}`,
OptyId: 1000 + index,
Name: `Synthetic opportunity ${index + 1} - Database migration`,
CustomerAccount: { PartyUniqueName: "Example public sector customer (Example City, BR)", PartyId: internalSrPreview || projectionPreview ? 789 : "test-party", PartyNumber: "test-account", Region_c_localizedValue: "LAD", PrimaryAddress: { CountryCode: "BR" } },
CustomerAccount: { PartyUniqueName: "Example public sector customer (Example City, BR)", PartyId: internalSrPreview || projectionPreview ? 789 : "100000810210835", PartyNumber: "test-account", Region_c_localizedValue: "LAD", PrimaryAddress: { CountryCode: "BR" } },
Owner: { PersonFirstName: "Example", PersonLastName: "Owner" },
PrimaryRevenue: { RevnAmountCurcyCode: "USD", RevnAmount: "25000", WinProb: 60 },
EffectiveDate: index === 24 ? null : `2026-11-${String(index < 8 ? 15 : 1 + index).padStart(2, "0")}T00:00:00Z`,
@@ -33,6 +33,10 @@
onMessage: { addListener: listener => listeners.push(listener) },
async sendMessage(message) {
const operation = message.type.split(".").at(-1);
if (operation === "loadOrganizationChart" || operation === "saveOrganizationChart") {
try { return await window.fixtureOrgStorage[operation === "loadOrganizationChart" ? "load" : "save"](message); }
catch (error) { return { ok: false, error: error.message }; }
}
if (operation === "requestWorkloadForecastUpdate") return { ok: true, result: null, debugRequests: [] };
if (operation === "requestWorkloads") return { ok: true, workloads: [{ id: 123, name: "Example workload",
adjustedACR: 50000, consumptionStartDate: "2026-11-15T00:00:00", forecast: Array.from({ length: 12 }, (_, index) => ({
@@ -97,9 +101,27 @@
const url = new URL(input);
let body;
if (url.pathname === "/fscmRestApi/tokenrelay") body = { access_token: "synthetic-fusion-token", expires_in: 3600 };
else if (url.pathname.endsWith("/opportunities")) {
if (window.fixtureOpportunitiesDelay) await new Promise(resolve => setTimeout(resolve, window.fixtureOpportunitiesDelay));
(window.fixtureOpportunitiesByContact ||= []).push(url.toString());
const offset = Number(url.searchParams.get("offset"));
body = { items: Array.from({length: offset ? 1 : 5}, (_, i) => ({ OptyNumber: "CONTACT" + (offset + i), Name: "Contact opportunity " + (offset + i), WinProb: 60, CurrencyCode: "BRL", Revenue: "5656658", EffectiveDate: "2024-05-08", StatusCode: "CLOSED" })), totalResults: 6, hasMore: offset === 0 };
}
else if (url.pathname.endsWith("custom-actions/queries")) {
if (options.method === "GET") return Response.json({ items: [{ isDefault: true, savedSearchNumber: "fixture-default" }] });
const { offset, limit, entity } = JSON.parse(options.body);
const { offset, limit, entity, keywords } = JSON.parse(options.body);
if (entity === "Contact") {
(window.fixtureContactQueries ||= []).push(keywords);
if (window.fixtureContactsFailure) return new Response("Synthetic contacts failure", { status: 503 });
const contacts = ["Alex Morgan", "Taylor Chen", "Jordan Silva", "Sam Rivera"].map((PartyName, index) => ({
PartyName, PartyId: String(2000 + index), PartyNumber: String(18000 + index),
JobTitle: ["Chief Technology Officer", "Infrastructure Director", "Data and Analytics Director", "Cloud Architect"][index],
PrimaryEmail: { EmailAddress: "contact" + index + "@example.invalid" }, PrimaryAccount: { PartyName: "Example Customer" }
}));
if (window.fixtureContactDelay?.[keywords]) await new Promise(resolve => setTimeout(resolve, window.fixtureContactDelay[keywords]));
(window.fixtureContactCompleted ||= []).push(keywords);
return Response.json({ items: contacts.filter(contact => contact.PartyId === keywords || contact.PartyName.toLowerCase().includes(keywords.toLowerCase())).map(contact => ({ ...contact, ...window.fixtureContactOverrides?.[contact.PartyId] })), hasMore: false });
}
if (entity === "CRMServiceRequest") return new Response(JSON.stringify({ items: [{ SrId: "123456", SrNumber: "SR123456", Title: "Example parent SR", PrimaryPillarNew_c: "Tech_Cloud_Infrastructure", CustomerDeadline_c: "2026-11-30T00:00:00.000+0000", ReportedHours_c: 4, OpportunityName_Id_c: { OptyNumber: "TEST1" } }], hasMore: false }), { status: 200 });
body = { items: opportunities.slice(offset, offset + limit), totalResults: opportunities.length, count: Math.min(limit, opportunities.length - offset), hasMore: offset + limit < opportunities.length, offset, limit };
} else if (url.pathname.endsWith("summarizations/generate")) body = { summaryText: "Synthetic AI summary.\nText is displayed safely: <script>never executed</script>." };