function createContentApplication(overrides = {}) { const environment = { document: globalThis.document, window: globalThis.window, navigator: globalThis.navigator, get localStorage() { return globalThis.localStorage; }, fetch: globalThis.fetch, browser: globalThis.browser, chrome: globalThis.chrome, MutationObserver: globalThis.MutationObserver, Node: globalThis.Node, requestAnimationFrame: globalThis.requestAnimationFrame, performance: globalThis.performance, cancelAnimationFrame: globalThis.cancelAnimationFrame, setTimeout: globalThis.setTimeout, clearTimeout: globalThis.clearTimeout, matchMedia: globalThis.matchMedia, ...overrides }; const messageTypes = createMessageTypes(); const currentUser = createCurrentUser({ environment, messageTypes, sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args) }); const contracts = createContentContracts(); const searchableSelect = createSearchableSelect({ environment }); const authSessionState = createAuthSessionState(contracts); const authSalesCommonState = createAuthSalesCommonState(); const opportunitiesQueryState = createOpportunitiesQueryState(); const opportunitiesTableState = createOpportunitiesTableState(); const opportunitiesFilterState = createOpportunitiesFilterState(contracts); const preferencesState = createPreferencesState(contracts); const activityCache = createActivityCache({ authSessionState, preferencesState, environment }); const productsContentState = createProductsContentState(); const aiSummaryState = createAiSummaryState(); const consumptionPlansState = createConsumptionPlansState(); const consumptionTrendState = createConsumptionTrendState(); const opportunitiesDashboardState = createOpportunitiesDashboardState(contracts); const debugState = createDebugState(); const columns = createOpportunitiesColumns({ formatOracleResponseDate: (...args) => opportunitiesFormatters.formatOracleResponseDate(...args), formatRevenue: (...args) => opportunitiesFormatters.formatRevenue(...args), formatWinProbability: (...args) => opportunitiesFormatters.formatWinProbability(...args), getNestedValue: (...args) => opportunitiesFormatters.getNestedValue(...args), getOwnerName: (...args) => opportunitiesFormatters.getOwnerName(...args) }); const contentFusionPage = createContentFusionPage({ ADD_ICON_SELECTOR: contracts.ADD_ICON_SELECTOR, ALLOWED_PATHS: contracts.ALLOWED_PATHS, SALES_GROUP_SELECTOR: contracts.SALES_GROUP_SELECTOR, TILE_ID: contracts.TILE_ID, TILE_LABEL_ID: contracts.TILE_LABEL_ID, appendPath: (...args) => svgPaths.appendPath(...args), openOpportunitiesModal: (...args) => contentModal.openOpportunitiesModal(...args), environment }); const contentModal = createContentModal({ createManageTimeButton: () => manageTime.createButton(), prepareSrSession: () => srSessionPreparation.ensure(), closeActionForm: (...args) => rampProjectionView.close(...args) || manageTime.close(...args) || internalSrForm.close(...args) || opportunityCalendar.closeDetails(...args) || crmSrForm.close(...args) || workloadActionForm.close(...args), mountOpportunityViews: (...args) => opportunityCalendar.mount(...args), createActivityFilterControls: (...args) => activityFilters.createControls(...args), closeCrmSrPopover: () => crmSrPopover.close(), ensureCurrentUser: () => currentUser.ensure(), ACCOUNT_PLANS_MODAL_ID: contracts.ACCOUNT_PLANS_MODAL_ID, AUTH_STATUS: contracts.AUTH_STATUS, CUSTOMER_FILTER_BUTTON_ID: contracts.CUSTOMER_FILTER_BUTTON_ID, CUSTOMER_FILTER_LIST_ID: contracts.CUSTOMER_FILTER_LIST_ID, CUSTOMER_FILTER_PANEL_ID: contracts.CUSTOMER_FILTER_PANEL_ID, CUSTOMER_FILTER_SEARCH_ID: contracts.CUSTOMER_FILTER_SEARCH_ID, CUSTOMER_FILTER_SELECT_ALL_ID: contracts.CUSTOMER_FILTER_SELECT_ALL_ID, DEBUG_PANEL_ID: contracts.DEBUG_PANEL_ID, ESCAPE_LISTENER_KEY: contracts.ESCAPE_LISTENER_KEY, MODAL_ID: contracts.MODAL_ID, OPPORTUNITIES_TABLE_ID: contracts.OPPORTUNITIES_TABLE_ID, OWNER_FILTER_BUTTON_ID: contracts.OWNER_FILTER_BUTTON_ID, OWNER_FILTER_LIST_ID: contracts.OWNER_FILTER_LIST_ID, OWNER_FILTER_PANEL_ID: contracts.OWNER_FILTER_PANEL_ID, OWNER_FILTER_SEARCH_ID: contracts.OWNER_FILTER_SEARCH_ID, OWNER_FILTER_SELECT_ALL_ID: contracts.OWNER_FILTER_SELECT_ALL_ID, PERIOD_OPTIONS: contracts.PERIOD_OPTIONS, PREFERENCES_MODAL_ID: contracts.PREFERENCES_MODAL_ID, PRODUCTS_CACHE_TIMESTAMP_ID: contracts.PRODUCTS_CACHE_TIMESTAMP_ID, PRODUCTS_PROGRESS_ID: contracts.PRODUCTS_PROGRESS_ID, STAGE_DASHBOARD_ID: contracts.STAGE_DASHBOARD_ID, STAGE_FILTERS_ID: contracts.STAGE_FILTERS_ID, STATUS_FILTERS_ID: contracts.STATUS_FILTERS_ID, TABLE_SEARCH_ID: contracts.TABLE_SEARCH_ID, applyTheme: (...args) => contentTheme.applyTheme(...args), authSessionState, closeAccountPlansModal: (...args) => consumptionPlansView.closeAccountPlansModal(...args), closeInstallBaseModal: (...args) => installBaseView.closeInstallBaseModal(...args), closeServiceRequestsModal: (...args) => serviceRequestsView.closeServiceRequestsModal(...args), closeCustomerFilterPanel: (...args) => opportunitiesFilters.closeCustomerFilterPanel(...args), closeOwnerFilterPanel: (...args) => opportunitiesFilters.closeOwnerFilterPanel(...args), closePreferencesModal: (...args) => preferencesView.closePreferencesModal(...args), createSettingsIcon: (...args) => contentIcons.createSettingsIcon(...args), createRefreshAllButton: (...args) => refreshAll.createButton(...args), debugState, ensureExtensionStyles: (...args) => contentStyles.ensureExtensionStyles(...args), getCustomerOptions: (...args) => opportunitiesFormatters.getCustomerOptions(...args), getOwnerOptions: (...args) => opportunitiesFormatters.getOwnerOptions(...args), getSavedOpportunityTypeValues: (...args) => preferencesStorage.getSavedOpportunityTypeValues(...args), getSavedOpptyProductsCacheHours: (...args) => preferencesStorage.getSavedOpptyProductsCacheHours(...args), getSavedTheme: (...args) => contentTheme.getSavedTheme(...args), openPreferencesModal: (...args) => preferencesView.openPreferencesModal(...args), opportunitiesFilterState, opportunitiesQueryState, preferencesState, renderCustomerFilter: (...args) => opportunitiesFilters.renderCustomerFilter(...args), renderCustomerFilterList: (...args) => opportunitiesFilters.renderCustomerFilterList(...args), renderOpportunitiesTable: (...args) => opportunitiesTable.renderOpportunitiesTable(...args), renderOwnerFilter: (...args) => opportunitiesFilters.renderOwnerFilter(...args), renderOwnerFilterList: (...args) => opportunitiesFilters.renderOwnerFilterList(...args), renderStageFilterButtons: (...args) => opportunitiesFilters.renderStageFilterButtons(...args), renderStatusFilterButtons: (...args) => opportunitiesFilters.renderStatusFilterButtons(...args), requestOpportunitiesForPeriod: (...args) => opportunitiesController.requestOpportunitiesForPeriod(...args), requestTokenRelayOnce: (...args) => authContentSession.requestTokenRelayOnce(...args), resetCustomerAndOwnerFiltersForPeriod: (...args) => opportunitiesFilters.resetCustomerAndOwnerFiltersForPeriod(...args), resetOpportunitiesTable: (...args) => opportunitiesController.resetOpportunitiesTable(...args), restoreFilterPreferences: (...args) => preferencesStorage.restoreFilterPreferences(...args), saveFilterPreferences: (...args) => preferencesStorage.saveFilterPreferences(...args), toggleCustomerFilterPanel: (...args) => opportunitiesFilters.toggleCustomerFilterPanel(...args), toggleDebugPanel: (...args) => debugContentView.toggleDebugPanel(...args), toggleOwnerFilterPanel: (...args) => opportunitiesFilters.toggleOwnerFilterPanel(...args), environment }); const contentTheme = createContentTheme({ THEME_STORAGE_KEY: contracts.THEME_STORAGE_KEY, createThemeIcon: (...args) => contentIcons.createThemeIcon(...args), environment }); const contentIcons = createContentIcons({ appendPath: (...args) => svgPaths.appendPath(...args), environment }); const svgPaths = createSvgPaths({ environment }); const manageTime = createManageTime({ MODAL_ID: contracts.MODAL_ID, environment, searchableSelect, dates: createTimeDates(), notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), async requestDelete(id) { await srSessionPreparation.ensure(); const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestTimeEntriesDelete, id }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to delete time entry."); return result.result; }, async requestSave(method, items) { await srSessionPreparation.ensure(); await currentUser.ensure(); const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestTimeEntriesSave, method, items, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to save time entries."); return result.result; }, async requestEntries(weekId) { await srSessionPreparation.ensure(); await currentUser.ensure(); const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestTimeEntries, weekId, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load time entries."); return result.items; }, async requestTaskTypes() { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestLookupTaskType }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load Task Types."); return result.items; }, async requestExpand(srNumbers) { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestServiceRequestExpand, srNumbers }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load activities."); return result.items; }, async requestServices(weekId) { await srSessionPreparation.ensure(); await currentUser.ensure(); const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestActiveServiceRequests, weekId, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load Service Requests."); return result.items; }, async requestWeek(dateReference) { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestWeekDetails, dateReference }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load week details."); return result.items; } }); const contentStyles = createContentStyles({ STYLE_ID: contracts.STYLE_ID, redwoodStyles, environment }); const authContentSession = createAuthContentSession({ messageTypes, AUTH_STATUS: contracts.AUTH_STATUS, appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), authSessionState, requestTokenRelay: (...args) => authTokenRelay.requestTokenRelay(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), updateAuthBadge: (...args) => contentModal.updateAuthBadge(...args) }); const authSalesCommon = createAuthSalesCommon({ TOKEN_RELAY_URL: contracts.TOKEN_RELAY_URL, authSalesCommonState, requestTokenRelay: (...args) => authTokenRelay.requestTokenRelay(...args) }); const authTokenRelay = createAuthTokenRelay({ authSessionState, TOKEN_RELAY_URL: contracts.TOKEN_RELAY_URL, createDebugBody: (...args) => debugContentLog.createDebugBody(...args), getXsrfToken: (...args) => authXsrfContent.getXsrfToken(...args), logRequestFailure: (...args) => debugContentLog.logRequestFailure(...args), logRequestStart: (...args) => debugContentLog.logRequestStart(...args), logRequestSuccess: (...args) => debugContentLog.logRequestSuccess(...args), maskToken: (...args) => debugContentLog.maskToken(...args), readResponseBodyForDebug: (...args) => debugContentLog.readResponseBodyForDebug(...args), refreshXsrfCookie: (...args) => platformContentMessages.refreshXsrfCookie(...args), renderDebugPanel: (...args) => debugContentView.renderDebugPanel(...args), environment }); const authXsrfContent = createAuthXsrfContent({ getXsrfTokenFromExtensionCookies: (...args) => platformContentMessages.getXsrfTokenFromExtensionCookies(...args), environment }); const platformContentMessages = createPlatformContentMessages({ requestCache: createFormRequestCache({ getHours: () => preferencesState.opptyProductsCacheHours, getUserId: () => currentUser.getUserId() }), messageTypes, environment }); const opportunitiesController = createOpportunitiesController({ ensureCurrentUser: () => currentUser.ensure(), resetWorkloadActions: (...args) => opportunityWorkloadActions.reset(...args), resetWorkloads: () => { rampProjectionView.close(false); productWorkloads.reset(); }, STAGE_OPTIONS: contracts.STAGE_OPTIONS, STATUS_OPTIONS: contracts.STATUS_OPTIONS, authSessionState, consumptionPlansState, consumptionTrendState, getFiscalPeriodRange: (...args) => opportunitiesFiscalPeriods.getFiscalPeriodRange(...args), opportunitiesDashboardState, opportunitiesFilterState, opportunitiesQueryState, opportunitiesTableState, preferencesState, productsContentState, renderProductsProgress: (...args) => productsContentJobs.renderProductsProgress(...args), requestOpportunitiesPage: (...args) => fusionOpportunities.requestOpportunitiesPage(...args), resetCrmServiceRequests: () => opportunityCrmServiceRequests.reset(), requestOpptyProductsInBackground: (...args) => productsContentJobs.requestOpptyProductsInBackground(...args), requestTokenRelayOnce: (...args) => authContentSession.requestTokenRelayOnce(...args), setOpportunitiesTableState: (...args) => opportunitiesTable.setOpportunitiesTableState(...args) }); const fusionOpportunities = createFusionOpportunities({ OPPORTUNITIES_PAGE_LIMIT: contracts.OPPORTUNITIES_PAGE_LIMIT, OPPORTUNITIES_QUERY_URL: contracts.OPPORTUNITIES_QUERY_URL, isCurrentPeriodRequest: (...args) => opportunitiesController.isCurrentPeriodRequest(...args), logRequestFailure: (...args) => debugContentLog.logRequestFailure(...args), logRequestStart: (...args) => debugContentLog.logRequestStart(...args), logRequestSuccess: (...args) => debugContentLog.logRequestSuccess(...args), maskToken: (...args) => debugContentLog.maskToken(...args), getOpportunityTypeValues: () => preferencesState.selectedOpportunityTypeValues, readResponseBodyForDebug: (...args) => debugContentLog.readResponseBodyForDebug(...args), environment }); const opportunitiesFiscalPeriods = createOpportunitiesFiscalPeriods(); const fusionCrmServiceRequests = createFusionCrmServiceRequests({ isCurrentPeriodRequest: (...args) => opportunitiesController.isCurrentPeriodRequest(...args), logRequestStart: (...args) => debugContentLog.logRequestStart(...args), logRequestSuccess: (...args) => debugContentLog.logRequestSuccess(...args), logRequestFailure: (...args) => debugContentLog.logRequestFailure(...args), readResponseBodyForDebug: (...args) => debugContentLog.readResponseBodyForDebug(...args), maskToken: (...args) => debugContentLog.maskToken(...args), environment }); const internalSrSession = createInternalSrSession({ environment, query: async srId => { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestInternalServiceRequest, srId }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); return result; } }); const crmSrPopover = createCrmSrPopover({ openInternalSrForm: (parent, trigger) => internalSrForm.open(parent, trigger), formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), requestDetails: srId => internalSrSession.request(srId), MODAL_ID: contracts.MODAL_ID, createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args), createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment }); const opportunityBadgeContent = createOpportunityBadgeContent({ environment }); async function requestSrFormLookup(type, fields = {}) { const result = await platformContentMessages.sendRuntimeMessage({ type, ...fields }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load Service Request options."); return result.items; } const internalSrForm = createInternalSrForm({ notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), requestSave: async payload => { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestPostInternalServiceRequest, payload, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to create Internal Service Request."); return result.result; }, getOpportunity: number => number == null ? null : opportunitiesTableState.opportunitiesTableState.items.find(item => String(item.OptyNumber) === String(number)), MODAL_ID: contracts.MODAL_ID, environment, searchableSelect, formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), requestPlatform: () => requestSrFormLookup(messageTypes.requestLookupTypePlatform), requestServices: parentServiceId => requestSrFormLookup(messageTypes.requestInternalSrServices, { parentServiceId, emailAddress: currentUser.getUserId() }) }); const crmSrForm = createCrmSrForm({ requestSave: async fields => { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestPostServiceRequest, ...fields, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to save Service Request."); return result; }, notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), getOpportunity: number => opportunitiesTableState.opportunitiesTableState.items.find(item => String(item.OptyNumber) === String(number)), formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), requestLanguage: () => requestSrFormLookup(messageTypes.requestSrLookupLanguage), requestPlatform: () => requestSrFormLookup(messageTypes.requestSrLookupTechPlatform), requestServices: () => requestSrFormLookup(messageTypes.requestSrLookupOpportunityBusiness, { emailAddress: currentUser.getUserId() }), searchableSelect, MODAL_ID: contracts.MODAL_ID, environment, allowsCrmActivities: () => currentUser.allowsCrmActivities(), isMissing: number => opportunityCrmServiceRequests.getSummary(number)?.state === "missing", createCloseIcon: () => contentIcons.createCloseIcon(), requestPillars: () => requestSrFormLookup(messageTypes.requestSrLookupPrimaryPillar) }); const opportunityCrmServiceRequests = createOpportunityCrmServiceRequests({ formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), createSrButton: number => crmSrForm.createButton(number), closeSrForm: () => { internalSrForm.close(false); crmSrForm.close(false); }, setBadgeContent: (...args) => opportunityBadgeContent.setContent(...args), activityCache, reportProgress: (...args) => activityProgress.update("sr", ...args), allowsCrmActivities: () => currentUser.allowsCrmActivities(), bindPopover: (...args) => crmSrPopover.bind(...args), closePopover: (...args) => crmSrPopover.close(...args), requestCrmServiceRequest: (...args) => fusionCrmServiceRequests.requestCrmServiceRequest(...args), isCurrentPeriodRequest: (...args) => opportunitiesController.isCurrentPeriodRequest(...args), environment }); const opportunityCalendar = createOpportunityCalendar({ createViewIcon: view => contentIcons.createViewIcon(view), environment, loadLibrary: () => loadOpportunityCalendarLibrary(), getState: () => opportunitiesTableState.opportunitiesTableState, getItems: () => opportunitiesFilters.getSortedOpportunities(), getVersion: () => opportunitiesQueryState.periodRequestVersion, formatRevenue: item => opportunitiesFormatters.formatRevenue(item), formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), getOwnerName: item => opportunitiesFormatters.getOwnerName(item), createDetailLink: (...args) => opportunitiesLinks.createDetailLink(...args), createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args), createCloseIcon: () => contentIcons.createCloseIcon(), createStageBadge: value => opportunitiesLinks.createStageBadge(value), createStatusBadge: value => opportunitiesLinks.createStatusBadge(value), opportunityUrl: contracts.OPPORTUNITY_DETAIL_URL, modalId: contracts.MODAL_ID, closeSrPopover: () => crmSrPopover.close() }); const opportunitiesTable = createOpportunitiesTable({ renderCalendar: (...args) => opportunityCalendar.render(...args), renderActivityFilters: () => activityFilters.render(), closeCrmSrPopover: (...args) => crmSrPopover.close(...args), createWorkloadActionsBadge: (...args) => opportunityWorkloadActions.createBadge(...args), ACCOUNT_DETAIL_URL: contracts.ACCOUNT_DETAIL_URL, OPPORTUNITIES_COLUMNS: columns, OPPORTUNITIES_TABLE_ID: contracts.OPPORTUNITIES_TABLE_ID, OPPORTUNITY_DETAIL_URL: contracts.OPPORTUNITY_DETAIL_URL, createCloudConsumptionButton: (...args) => consumptionPlansAction.createCloudConsumptionButton(...args), createInstallBaseButton: (...args) => installBaseAction.createInstallBaseButton(...args), createServiceRequestsButton: (...args) => serviceRequestsAction.createServiceRequestsButton(...args), createCopyOpportunityButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args), createDetailLink: (...args) => opportunitiesLinks.createDetailLink(...args), createProductsCountButton: (...args) => productsDetails.createProductsCountButton(...args), createProductsRampBadge: (...args) => productsDetails.createProductsRampBadge(...args), createProjectionIndicator: (...args) => rampProjectionView.createOpportunityIndicator(...args), createCrmServiceRequestBadge: (...args) => opportunityCrmServiceRequests.createBadge(...args), createProductsDetailRow: (...args) => productsDetails.createProductsDetailRow(...args), createStageBadge: (...args) => opportunitiesLinks.createStageBadge(...args), createStatusBadge: (...args) => opportunitiesLinks.createStatusBadge(...args), displayOpportunityValue: (...args) => opportunitiesFormatters.displayOpportunityValue(...args), getNestedValue: (...args) => opportunitiesFormatters.getNestedValue(...args), getSortedOpportunities: (...args) => opportunitiesFilters.getSortedOpportunities(...args), opportunitiesTableState, productsContentState, renderCustomerFilter: (...args) => opportunitiesFilters.renderCustomerFilter(...args), renderOwnerFilter: (...args) => opportunitiesFilters.renderOwnerFilter(...args), renderStageDashboard: (...args) => opportunitiesDashboard.renderStageDashboard(...args), resetCustomerFilter: (...args) => opportunitiesFilters.resetCustomerFilter(...args), resetOwnerFilter: (...args) => opportunitiesFilters.resetOwnerFilter(...args), environment }); const opportunitiesDashboard = createOpportunitiesDashboard({ STAGE_DASHBOARD_ID: contracts.STAGE_DASHBOARD_ID, STAGE_OPTIONS: contracts.STAGE_OPTIONS, getNestedValue: (...args) => opportunitiesFormatters.getNestedValue(...args), opportunitiesDashboardState, environment }); const opportunitiesFilters = createOpportunitiesFilters({ matchesActivities: item => activityFilters.matches(item), CUSTOMER_FILTER_BUTTON_ID: contracts.CUSTOMER_FILTER_BUTTON_ID, CUSTOMER_FILTER_LIST_ID: contracts.CUSTOMER_FILTER_LIST_ID, CUSTOMER_FILTER_PANEL_ID: contracts.CUSTOMER_FILTER_PANEL_ID, CUSTOMER_FILTER_SEARCH_ID: contracts.CUSTOMER_FILTER_SEARCH_ID, CUSTOMER_FILTER_SELECT_ALL_ID: contracts.CUSTOMER_FILTER_SELECT_ALL_ID, OPPORTUNITIES_COLUMNS: columns, OWNER_FILTER_BUTTON_ID: contracts.OWNER_FILTER_BUTTON_ID, OWNER_FILTER_LIST_ID: contracts.OWNER_FILTER_LIST_ID, OWNER_FILTER_PANEL_ID: contracts.OWNER_FILTER_PANEL_ID, OWNER_FILTER_SEARCH_ID: contracts.OWNER_FILTER_SEARCH_ID, OWNER_FILTER_SELECT_ALL_ID: contracts.OWNER_FILTER_SELECT_ALL_ID, STAGE_FILTERS_ID: contracts.STAGE_FILTERS_ID, STAGE_OPTIONS: contracts.STAGE_OPTIONS, STATUS_FILTERS_ID: contracts.STATUS_FILTERS_ID, STATUS_OPTIONS: contracts.STATUS_OPTIONS, getCustomerFilterSummary: (...args) => opportunitiesFormatters.getCustomerFilterSummary(...args), getCustomerKey: (...args) => opportunitiesFormatters.getCustomerKey(...args), getCustomerOptions: (...args) => opportunitiesFormatters.getCustomerOptions(...args), getOwnerKey: (...args) => opportunitiesFormatters.getOwnerKey(...args), getOwnerOptions: (...args) => opportunitiesFormatters.getOwnerOptions(...args), opportunitiesFilterState, opportunitiesTableState, renderOpportunitiesTable: (...args) => opportunitiesTable.renderOpportunitiesTable(...args), saveFilterPreferences: (...args) => preferencesStorage.saveFilterPreferences(...args), stringifySearchValue: (...args) => opportunitiesFormatters.stringifySearchValue(...args), environment }); const opportunitiesFormatters = createOpportunitiesFormatters({ opportunitiesTableState }); const opportunitiesLinks = createOpportunitiesLinks({ MODAL_ID: contracts.MODAL_ID, environment }); const preferencesStorage = createPreferencesStorage({ DEFAULT_OPPORTUNITY_TYPE_VALUES: contracts.DEFAULT_OPPORTUNITY_TYPE_VALUES, DEFAULT_OPPTY_PRODUCTS_CACHE_HOURS: contracts.DEFAULT_OPPTY_PRODUCTS_CACHE_HOURS, FILTER_PREFERENCES_STORAGE_KEY: contracts.FILTER_PREFERENCES_STORAGE_KEY, MODAL_ID: contracts.MODAL_ID, OPPORTUNITY_TYPE_OPTIONS: contracts.OPPORTUNITY_TYPE_OPTIONS, OPPORTUNITY_TYPE_PREFERENCES_STORAGE_KEY: contracts.OPPORTUNITY_TYPE_PREFERENCES_STORAGE_KEY, OPPTY_PRODUCTS_CACHE_OPTIONS: contracts.OPPTY_PRODUCTS_CACHE_OPTIONS, PERIOD_OPTIONS: contracts.PERIOD_OPTIONS, STAGE_OPTIONS: contracts.STAGE_OPTIONS, STATUS_OPTIONS: contracts.STATUS_OPTIONS, opportunitiesFilterState, environment }); const preferencesView = createPreferencesView({ DEFAULT_OPPTY_PRODUCTS_CACHE_HOURS: contracts.DEFAULT_OPPTY_PRODUCTS_CACHE_HOURS, MODAL_ID: contracts.MODAL_ID, OPPORTUNITY_TYPE_OPTIONS: contracts.OPPORTUNITY_TYPE_OPTIONS, OPPORTUNITY_TYPE_PREFERENCES_STORAGE_KEY: contracts.OPPORTUNITY_TYPE_PREFERENCES_STORAGE_KEY, OPPTY_PRODUCTS_CACHE_OPTIONS: contracts.OPPTY_PRODUCTS_CACHE_OPTIONS, PERIOD_OPTIONS: contracts.PERIOD_OPTIONS, PREFERENCES_MODAL_ID: contracts.PREFERENCES_MODAL_ID, createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), getSavedOpportunityTypeValues: (...args) => preferencesStorage.getSavedOpportunityTypeValues(...args), getSavedOpptyProductsCacheHours: (...args) => preferencesStorage.getSavedOpptyProductsCacheHours(...args), preferencesState, requestOpportunitiesForPeriod: (...args) => opportunitiesController.requestOpportunitiesForPeriod(...args), environment }); const refreshAll = createRefreshAll({ createRefreshIcon: () => contentIcons.createRefreshIcon(), messageTypes, activityCache, opportunitiesQueryState, productsContentState, consumptionPlansState, consumptionTrendState, aiSummaryState, environment, sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), reload: (...args) => opportunitiesController.requestOpportunitiesForPeriod(...args), onFailure: error => opportunitiesTable.setOpportunitiesTableState({ status: "error", message: error.message || "Unable to refresh cached data." }), notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), resetRelatedData: () => { opportunityCrmServiceRequests.reset(); opportunityWorkloadActions.reset(); productWorkloads.reset(); rampProjectionView.close(false); consumptionPlansView.closeAccountPlansModal(); installBaseView.closeInstallBaseModal(); serviceRequestsView.closeServiceRequestsModal(); installBaseAction.resetRequests(); serviceRequestsAction.resetRequests(); ratecardController.resetRequests(); consumptionPlanDetailController.resetRequests(); productsContentJobs.renderProductsProgress(); opportunitiesTable.setOpportunitiesTableState({ status: "loading", message: "Refreshing data..." }); } }); const activityProgress = createActivityProgress({ MODAL_ID: contracts.MODAL_ID, environment }); const srSessionPreparation = createSrSessionPreparation({ async onReady() { const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestResourceUser, emailAddress: currentUser.getUserId() }); debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []); if (!result?.ok) throw new Error(result?.error || "Unable to load resource user."); }, ensureCurrentUser: () => currentUser.ensure(), allowsCrmActivities: () => currentUser.allowsCrmActivities(), sendRequest: () => platformContentMessages.sendRuntimeMessage({ type: messageTypes.prepareSrSession }), reportProgress: state => { activityProgress.update("session", state); manageTime.setReady(state === "complete"); }, appendLog: entries => debugContentLog.appendBackgroundRequestLog(entries) }); const activityFilters = createActivityFilters({ setBadgeContent: (...args) => opportunityBadgeContent.setContent(...args), allowsCrmActivities: () => currentUser.allowsCrmActivities(), getSrSummary: number => opportunityCrmServiceRequests.getSummary(number), getActionSummary: number => opportunityWorkloadActions.getSummary(number), renderTable: () => opportunitiesTable.renderOpportunitiesTable(), environment }); const productActivities = createProductActivities({ productsContentState, opportunitiesQueryState, loadCrm: (...args) => opportunityCrmServiceRequests.load(...args), loadActions: (...args) => opportunityWorkloadActions.loadProducts(...args), blockActions: products => opportunityWorkloadActions.blockProducts(products), render: () => { productsContentJobs.renderProductsProgress(); productsContentJobs.queueProductsTableRender(); } }); const productsContentJobs = createProductsContentJobs({ loadWorkloads: (...args) => productWorkloads.load(...args), joinWorkloads: number => productWorkloads.joinProducts(number), beginProductActivities: (...args) => productActivities.begin(...args), completeProductActivities: (...args) => productActivities.complete(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), messageTypes, PRODUCTS_CACHE_TIMESTAMP_ID: contracts.PRODUCTS_CACHE_TIMESTAMP_ID, PRODUCTS_MESSAGE_LISTENER_KEY: contracts.PRODUCTS_MESSAGE_LISTENER_KEY, PRODUCTS_PROGRESS_ID: contracts.PRODUCTS_PROGRESS_ID, preferencesState, productsContentState, renderOpportunitiesTable: (...args) => opportunitiesTable.renderOpportunitiesTable(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), environment }); const productWorkloads = createProductWorkloads({ productsContentState, opportunitiesQueryState, preferencesState, messageTypes, requestConsumerTokenServiceOnce: () => authContentSession.requestConsumerTokenServiceOnce(), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), getPrincipal: () => currentUser.getUserId() || authSessionState.principal, queueProductsTableRender: () => productsContentJobs.queueProductsTableRender() }); const workloadActionOptions = createWorkloadActionOptions({ requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), messageTypes }); const workloadActionForm = createWorkloadActionForm({ searchableSelect, onActionSaved: (...args) => opportunityWorkloadActions.applySavedAction(...args), saveAction: (...args) => workloadActionOptions.save(...args), notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), getCurrentUserId: () => currentUser.getUserId(), requestTeamMembers: (...args) => workloadActionOptions.requestTeamMembers(...args), requestLookup: (...args) => workloadActionOptions.requestLookup(...args), getProducts: number => productsContentState.opptyProductsByNumber.get(String(number))?.items || [], getOpportunity: number => opportunitiesTableState.opportunitiesTableState.items.find(item => String(item.OptyNumber) === String(number)), formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), MODAL_ID: contracts.MODAL_ID, allowsCrmActivities: () => currentUser.allowsCrmActivities(), isMissingAction: number => opportunityWorkloadActions.getSummary(number)?.state === "missing", createCloseIcon: () => contentIcons.createCloseIcon(), environment }); const opportunityWorkloadActions = createOpportunityWorkloadActions({ setBadgeContent: (...args) => opportunityBadgeContent.setContent(...args), createActionButton: number => workloadActionForm.createButton(number), closeActionForm: (...args) => workloadActionForm.close(...args), activityCache, reportProgress: (...args) => activityProgress.update("actions", ...args), allowsCrmActivities: () => currentUser.allowsCrmActivities(), authSessionState, requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), queueProductsTableRender: () => productsContentJobs.queueProductsTableRender(), productsContentState, messageTypes, environment }); const productsDetails = createProductsDetails({ createProjectionIndicator: (...args) => rampProjectionView.createIndicator(...args), setBadgeContent: (...args) => opportunityBadgeContent.setContent(...args), OPPORTUNITIES_COLUMNS: columns, createAiSummaryAlert: (...args) => aiSummaryContent.createAiSummaryAlert(...args), formatOracleResponseDate: (...args) => opportunitiesFormatters.formatOracleResponseDate(...args), productsContentState, renderOpportunitiesTable: (...args) => opportunitiesTable.renderOpportunitiesTable(...args), requestGenerateAiSummary: (...args) => aiSummaryContent.requestGenerateAiSummary(...args), environment }); const rampProjection = createRampProjection(); const workloadForecastUpdate = createWorkloadForecastUpdate({ compare: product => rampProjection.compare(product), ensureCurrentUser: () => currentUser.ensure(), getCurrentUserId: () => currentUser.getUserId(), requestAuthorization: () => authContentSession.requestConsumerTokenServiceOnce(), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), messageTypes, appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), productsContentState, queueProductsTableRender: () => productsContentJobs.queueProductsTableRender() }); const rampProjectionView = createRampProjectionView({ saveEstimates: product => workloadForecastUpdate.save(product), notify: (...args) => opportunitiesLinks.showCopyConfirmation(...args), MODAL_ID: contracts.MODAL_ID, compare: product => rampProjection.compare(product), expandProducts: number => productsDetails.expandProducts(number), createAlertIcon: () => contentIcons.createAlertIcon(), createCloseIcon: () => contentIcons.createCloseIcon(), formatAmount: (...args) => productsDetails.formatProductAmount(...args), formatDate: value => opportunitiesFormatters.formatOracleResponseDate(value), environment }); const aiSummaryContent = createAiSummaryContent({ aiSummaryState, invalidateSalesCommonToken: (...args) => authSalesCommon.invalidateSalesCommonToken(...args), logRequestFailure: (...args) => debugContentLog.logRequestFailure(...args), logRequestStart: (...args) => debugContentLog.logRequestStart(...args), logRequestSuccess: (...args) => debugContentLog.logRequestSuccess(...args), readResponseBodyForDebug: (...args) => debugContentLog.readResponseBodyForDebug(...args), requestTokenRelaySalesCommon: (...args) => authSalesCommon.requestTokenRelaySalesCommon(...args), environment }); const customerTableSearch = createCustomerTableSearch({ environment }); const installBaseView = createInstallBaseView({ createSearch: (...args) => customerTableSearch.createSearch(...args), MODAL_ID: contracts.MODAL_ID, createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), formatOracleResponseDate: (...args) => opportunitiesFormatters.formatOracleResponseDate(...args), environment }); const installBaseAction = createInstallBaseAction({ messageTypes, requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), openInstallBaseModal: (...args) => installBaseView.openInstallBaseModal(...args), environment }); const serviceRequestsView = createServiceRequestsView({ createSearch: (...args) => customerTableSearch.createSearch(...args), MODAL_ID: contracts.MODAL_ID, createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), formatOracleResponseDate: (...args) => opportunitiesFormatters.formatOracleResponseDate(...args), environment }); const serviceRequestsAction = createServiceRequestsAction({ messageTypes, requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), openServiceRequestsModal: (...args) => serviceRequestsView.openServiceRequestsModal(...args), environment }); const consumptionPlansAction = createConsumptionPlansAction({ messageTypes, appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), consumptionPlansState, getNestedValue: (...args) => opportunitiesFormatters.getNestedValue(...args), openAccountPlansModal: (...args) => consumptionPlansView.openAccountPlansModal(...args), renderOpportunitiesTable: (...args) => opportunitiesTable.renderOpportunitiesTable(...args), requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), showCopyConfirmation: (...args) => opportunitiesLinks.showCopyConfirmation(...args), environment }); const consumptionPlanDetailView = createConsumptionPlanDetailView({ createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment }); const consumptionPlanDetailController = createConsumptionPlanDetailController({ messageTypes, requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), renderPlanDetailBadges: (...args) => consumptionPlanDetailView.renderPlanDetailBadges(...args), environment }); const ratecardModel = createRatecardModel(); const consumptionHeaderView = createConsumptionHeaderView({ createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), formatOracleResponseDate: (...args) => opportunitiesFormatters.formatOracleResponseDate(...args), environment }); const ratecardView = createRatecardView({ ACCOUNT_PLANS_MODAL_ID: contracts.ACCOUNT_PLANS_MODAL_ID, columns: ratecardModel.columns, formatValue: (...args) => ratecardModel.formatValue(...args), selectItems: (...args) => ratecardModel.selectItems(...args), createPlanDetails: (...args) => consumptionHeaderView.createDetails(...args), createConsumptionHeader: (...args) => consumptionHeaderView.createHeader(...args), environment }); const ratecardController = createRatecardController({ messageTypes, requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), openRatecardDrawer: (...args) => ratecardView.openRatecardDrawer(...args), closePlanDetailPopover: (...args) => consumptionPlanDetailView.closePlanDetailPopover(...args), environment }); const consumptionPlansView = createConsumptionPlansView({ ACCOUNT_PLANS_MODAL_ID: contracts.ACCOUNT_PLANS_MODAL_ID, DEFAULT_CONSUMPTION_TREND_PERIOD: contracts.DEFAULT_CONSUMPTION_TREND_PERIOD, MODAL_ID: contracts.MODAL_ID, createConsumptionHeader: (...args) => consumptionHeaderView.createHeader(...args), createConsumptionTrendSection: (...args) => consumptionTrendController.createConsumptionTrendSection(...args), loadPlanDetailForPanel: (...args) => consumptionPlanDetailController.loadPlanDetailForPanel(...args), closePlanDetailPopover: (...args) => consumptionPlanDetailView.closePlanDetailPopover(...args), createRatecardButton: (...args) => ratecardController.createRatecardButton(...args), closeRatecardDrawer: (...args) => ratecardView.closeRatecardDrawer(...args), createSvgElement: (...args) => consumptionChart.createSvgElement(...args), createPlanDetails: (...args) => consumptionHeaderView.createDetails(...args), getNestedValue: (...args) => opportunitiesFormatters.getNestedValue(...args), loadConsumptionTrendForPanel: (...args) => consumptionTrendController.loadConsumptionTrendForPanel(...args), environment }); const consumptionTrendController = createConsumptionTrendController({ createPlanDetailSection: (...args) => consumptionPlanDetailController.createPlanDetailSection(...args), messageTypes, CONSUMPTION_TREND_PERIODS: contracts.CONSUMPTION_TREND_PERIODS, DEFAULT_CONSUMPTION_TREND_PERIOD: contracts.DEFAULT_CONSUMPTION_TREND_PERIOD, appendBackgroundRequestLog: (...args) => debugContentLog.appendBackgroundRequestLog(...args), consumptionTrendState, renderConsumptionTrendChart: (...args) => consumptionChart.renderConsumptionTrendChart(...args), requestConsumerTokenServiceOnce: (...args) => authContentSession.requestConsumerTokenServiceOnce(...args), sendRuntimeMessage: (...args) => platformContentMessages.sendRuntimeMessage(...args), environment }); const consumptionChart = createConsumptionChart({ CONSUMPTION_TREND_PERIODS: contracts.CONSUMPTION_TREND_PERIODS, CONSUMPTION_TREND_SERIES: contracts.CONSUMPTION_TREND_SERIES, SVG_NAMESPACE: contracts.SVG_NAMESPACE, calculateAverageConsumption: (...args) => consumptionModel.calculateAverageConsumption(...args), consumptionTrendState, createConsumptionTrendKey: (...args) => consumptionTrendController.createConsumptionTrendKey(...args), createNiceConsumptionMaximum: (...args) => consumptionModel.createNiceConsumptionMaximum(...args), formatCompactConsumptionNumber: (...args) => consumptionModel.formatCompactConsumptionNumber(...args), formatConsumptionCurrency: (...args) => consumptionModel.formatConsumptionCurrency(...args), formatConsumptionPointLabel: (...args) => consumptionModel.formatConsumptionPointLabel(...args), formatConsumptionRange: (...args) => consumptionModel.formatConsumptionRange(...args), normalizeConsumptionTrendItems: (...args) => consumptionModel.normalizeConsumptionTrendItems(...args), environment }); const consumptionModel = createConsumptionModel({ }); const debugContentLog = createDebugContentLog({ previewDebugBody: createDebugBodyPreview, debugState, renderDebugPanel: (...args) => debugContentView.renderDebugPanel(...args) }); const debugContentView = createDebugContentView({ createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), DEBUG_PANEL_ID: contracts.DEBUG_PANEL_ID, MODAL_ID: contracts.MODAL_ID, debugState, formatDebugBody: (...args) => debugContentLog.formatDebugBody(...args), formatHeaderBlock: (...args) => debugContentLog.formatHeaderBlock(...args), formatMetadataBlock: (...args) => debugContentLog.formatMetadataBlock(...args), environment }); function start() { startContentApplication({ environment, page: contentFusionPage, styles: contentStyles, products: productsContentJobs }); } return { opportunityCalendar, workloadActionForm, activityFilters, start, contracts, opportunityWorkloadActions, fusionCrmServiceRequests, opportunityCrmServiceRequests, authSessionState, authSalesCommonState, opportunitiesQueryState, opportunitiesTableState, opportunitiesFilterState, preferencesState, productsContentState, aiSummaryState, consumptionPlansState, consumptionTrendState, opportunitiesDashboardState, debugState, contentFusionPage, contentModal, contentTheme, contentIcons, contentStyles, authContentSession, currentUser, authSalesCommon, authTokenRelay, authXsrfContent, platformContentMessages, opportunitiesController, fusionOpportunities, opportunitiesFiscalPeriods, opportunitiesTable, opportunitiesDashboard, opportunitiesFilters, opportunitiesFormatters, opportunitiesLinks, preferencesStorage, preferencesView, productsContentJobs, productWorkloads, productActivities, activityProgress, srSessionPreparation, refreshAll, activityCache, productsDetails, rampProjection, workloadForecastUpdate, rampProjectionView, aiSummaryContent, consumptionPlansAction, installBaseAction, installBaseView, serviceRequestsAction, serviceRequestsView, consumptionPlansView, consumptionPlanDetailController, consumptionPlanDetailView, ratecardModel, ratecardView, ratecardController, consumptionTrendController, consumptionChart, consumptionModel, debugContentLog, debugContentView }; }