@eric-emg/symphiq-components 1.2.411 → 1.2.413

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -540,9 +540,30 @@ class ModalService {
540
540
  };
541
541
  this.modalState.next(newState);
542
542
  }
543
- openStrategyRecommendationsModal(strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId) {
543
+ openStrategyRecommendationsModal(strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId, goal, objective) {
544
544
  const data = { strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId };
545
- this.modalState.next({ type: 'strategy-recommendations', data, charts: [], previousState: null, navigationStack: [] });
545
+ const navigationStack = [];
546
+ if (goal) {
547
+ const goalObjectivesData = { goal, viewMode };
548
+ navigationStack.push({
549
+ type: 'goal-objectives',
550
+ data: goalObjectivesData,
551
+ charts: [],
552
+ previousState: null,
553
+ navigationStack: []
554
+ });
555
+ }
556
+ if (objective && goalTitle) {
557
+ const objectiveStrategiesData = { objective, goalTitle, viewMode };
558
+ navigationStack.push({
559
+ type: 'objective-strategies',
560
+ data: objectiveStrategiesData,
561
+ charts: [],
562
+ previousState: null,
563
+ navigationStack: []
564
+ });
565
+ }
566
+ this.modalState.next({ type: 'strategy-recommendations', data, charts: [], previousState: null, navigationStack });
546
567
  }
547
568
  openCategoryDetailModal(category, viewMode, scrollToSection) {
548
569
  const data = { category, viewMode, scrollToSection };
@@ -67651,9 +67672,9 @@ class SymphiqBusinessAnalysisDashboardComponent {
67651
67672
  }, 500);
67652
67673
  }
67653
67674
  openRecommendationDetailsModal(recommendation) {
67654
- // Create an adapter to match ProfileItemInterface structure
67655
67675
  const itemAdapter = {
67656
67676
  ...recommendation,
67677
+ type: 'RECOMMENDATION',
67657
67678
  label: recommendation.title,
67658
67679
  value: recommendation.description
67659
67680
  };
@@ -68068,259 +68089,259 @@ class SymphiqBusinessAnalysisDashboardComponent {
68068
68089
  }
68069
68090
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SymphiqBusinessAnalysisDashboardComponent, [{
68070
68091
  type: Component,
68071
- args: [{ selector: 'symphiq-business-analysis-dashboard', standalone: true, imports: [CommonModule, ProfileSectionComponent, SectionNavigationComponent, FloatingTocComponent, FloatingBackButtonComponent, TooltipContainerComponent, SectionDividerComponent, BusinessAnalysisModalComponent, SearchButtonComponent, SearchModalComponent, ViewModeSwitcherModalComponent, JourneyProgressIndicatorComponent, WelcomeBannerComponent, RecommendationsTiledGridComponent, CollapsibleSectionGroupComponent, ContentGenerationProgressWithConfettiComponent, IndeterminateSpinnerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
68072
- <div [ngClass]="getContainerClasses()">
68073
- <!-- Scroll Progress Bar (fixed at top) -->
68074
- <div [class]="embedded() ? 'sticky top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30' : 'fixed top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30'">
68075
- <div
68076
- [style.width.%]="scrollProgress()"
68077
- [ngClass]="isLightMode() ? 'bg-gradient-to-r from-blue-500 to-purple-500' : 'bg-gradient-to-r from-blue-400 to-purple-400'"
68078
- class="h-full transition-all duration-200 ease-out">
68079
- </div>
68080
- </div>
68081
-
68082
- <div class="animated-bubbles" [class.light-mode]="isLightMode()" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none;"></div>
68083
-
68084
- <div class="relative z-[51]">
68085
- <header [ngClass]="getHeaderClasses()" class="sticky top-0 z-50">
68086
- <!-- Expanded Header (default state) -->
68087
- <div
68088
- class="transition-all duration-300 ease-in-out overflow-hidden"
68089
- [class.max-h-0]="headerScrollService.isScrolled()"
68090
- [class.opacity-0]="headerScrollService.isScrolled()"
68091
- [class.max-h-96]="!headerScrollService.isScrolled()"
68092
- [class.opacity-100]="!headerScrollService.isScrolled()">
68093
- <div
68094
- class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"
68095
- [class.pointer-events-none]="headerScrollService.isScrolled()"
68096
- [class.pointer-events-auto]="!headerScrollService.isScrolled()">
68097
- <div class="flex items-center justify-between">
68098
- <div>
68099
- <h1 [ngClass]="getMainTitleClasses()">
68100
- {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68101
- </h1>
68102
- <p [ngClass]="getSubtitleClasses()">
68103
- Business Profile & Analysis
68104
- </p>
68105
- </div>
68106
- @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68107
- <div class="flex items-center gap-2">
68108
- <symphiq-search-button
68109
- [isLightMode]="isLightMode()"
68110
- (searchClick)="openSearch()"
68111
- />
68112
- <button
68113
- type="button"
68114
- (click)="openViewModeSwitcher()"
68115
- [ngClass]="getViewModeButtonClasses()"
68116
- class="cursor-pointer flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68117
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68118
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68119
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68120
- </svg>
68121
- <span>{{ displayModeLabel() }}</span>
68122
- </button>
68123
- </div>
68124
- }
68125
- </div>
68126
- </div>
68127
- </div>
68128
-
68129
- <!-- Condensed Header (scrolled state) -->
68130
- <div
68131
- class="transition-all duration-300 ease-in-out overflow-hidden"
68132
- [class.max-h-0]="!headerScrollService.isScrolled()"
68133
- [class.opacity-0]="!headerScrollService.isScrolled()"
68134
- [class.max-h-20]="headerScrollService.isScrolled()"
68135
- [class.opacity-100]="headerScrollService.isScrolled()">
68136
- <div
68137
- class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3"
68138
- [class.pointer-events-none]="!headerScrollService.isScrolled()"
68139
- [class.pointer-events-auto]="headerScrollService.isScrolled()">
68140
- <div class="flex items-center justify-between">
68141
- <div class="flex-1 min-w-0 mr-4">
68142
- <h1 [ngClass]="isLightMode() ? 'text-xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent truncate' : 'text-xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent truncate'">
68143
- {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68144
- </h1>
68145
- </div>
68146
- <div class="flex items-center gap-4">
68147
- @if (!isSimplifiedView()) {
68148
- <div class="flex items-center gap-2 text-sm flex-shrink-0">
68149
- <span [ngClass]="isLightMode() ? 'text-slate-600 font-medium' : 'text-slate-400 font-medium'" class="transition-opacity duration-300" [class.opacity-0]="sectionTitleFading()" [class.opacity-100]="!sectionTitleFading()">
68150
- {{ currentSectionTitle() }}
68151
- </span>
68152
- @if (currentSubsectionTitle()) {
68153
- <span [ngClass]="isLightMode() ? 'text-slate-400' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">›</span>
68154
- <span [ngClass]="isLightMode() ? 'text-slate-500' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">
68155
- {{ currentSubsectionTitle() }}
68156
- </span>
68157
- }
68158
- </div>
68159
- }
68160
- @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68161
- <symphiq-search-button
68162
- [isLightMode]="isLightMode()"
68163
- [minimized]="true"
68164
- (searchClick)="openSearch()"
68165
- />
68166
- <button
68167
- type="button"
68168
- (click)="openViewModeSwitcher()"
68169
- [ngClass]="getViewModeButtonClasses()"
68170
- class="cursor-pointer flex items-center gap-2 px-2 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68171
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68172
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68173
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68174
- </svg>
68175
- </button>
68176
- }
68177
- </div>
68178
- </div>
68179
- </div>
68180
- </div>
68181
- </header>
68182
-
68183
- <main class="relative">
68184
- @if (isLoading()) {
68185
- <!-- Pure Loading State -->
68186
- <div class="flex items-center justify-center min-h-[60vh]">
68187
- <symphiq-indeterminate-spinner
68188
- [viewMode]="viewMode()"
68189
- size="large"
68190
- />
68191
- </div>
68192
- } @else if (isContentGenerating()) {
68193
- <!-- Journey Progress Banner (always show when not onboarded) -->
68194
- @if (!isOnboarded()) {
68195
- <symphiq-journey-progress-indicator
68196
- [viewMode]="viewMode()"
68197
- [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68198
- [showNextStepAction]="false"
68199
- [forDemo]="forDemo()"
68200
- [maxAccessibleStepId]="maxAccessibleStepId()"
68201
- (stepClick)="stepClick.emit($event)"
68202
- (nextStepClick)="nextStepClick.emit()"
68203
- />
68204
- }
68205
-
68206
- <!-- Content Generation Progress Component -->
68207
- <symphiq-content-generation-progress-with-confetti
68208
- [viewMode]="viewMode()"
68209
- [itemStatus]="itemStatus()"
68210
- [currentStatus]="profile()?.selfContentStatus"
68211
- [confettiIntensity]="'celebration'"
68212
- [title]="'We are generating a new Business Analysis for ' + (currentProfile()?.profileStructured?.businessName || 'your business') + '.'"
68213
- [subtitle]="'It will appear here when ready. You can check back later as this will take a few minutes to complete.'"
68214
- />
68215
- } @else {
68216
- @if (isSimplifiedView()) {
68217
- <!-- Journey Progress Banner - Full Width Sticky (only show when not onboarded) -->
68218
- @if (!isOnboarded()) {
68219
- <symphiq-journey-progress-indicator
68220
- [viewMode]="viewMode()"
68221
- [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68222
- [showNextStepAction]="showNextStepAction()"
68223
- [forDemo]="forDemo()"
68224
- [maxAccessibleStepId]="maxAccessibleStepId()"
68225
- (stepClick)="stepClick.emit($event)"
68226
- (nextStepClick)="nextStepClick.emit()"
68227
- />
68228
- }
68229
-
68230
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
68231
- <div class="mb-8">
68232
- <symphiq-welcome-banner
68233
- [viewMode]="viewMode()"
68234
- [businessName]="currentProfile()?.profileStructured?.businessName || 'your business'"
68235
- [isOnboarded]="isOnboarded()"
68236
- />
68237
- </div>
68238
-
68239
- <div class="mb-8">
68240
- <symphiq-recommendations-tiled-grid
68241
- [recommendations]="recommendationItems()"
68242
- [viewMode]="viewMode()"
68243
- (viewMoreClick)="openRecommendationDetailsModal($event)"
68244
- />
68245
- </div>
68246
-
68247
- <div>
68248
- <symphiq-collapsible-section-group
68249
- [sections]="nonRecommendationSections()"
68250
- [viewMode]="viewMode()"
68251
- />
68252
- </div>
68253
- </div>
68254
- } @else {
68255
- @for (section of sections(); track trackBySectionId($index, section); let idx = $index; let last = $last) {
68256
- <symphiq-profile-section
68257
- [section]="section"
68258
- [viewMode]="viewMode()"
68259
- [forceExpanded]="!isCompactView()"
68260
- />
68261
- @if (!last) {
68262
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
68263
- <symphiq-section-divider
68264
- [viewMode]="viewMode()"
68265
- [subsections]="sections()[idx + 1].subsections || []" />
68266
- </div>
68267
- }
68268
- }
68269
- }
68270
- }
68271
- </main>
68272
-
68273
- @if (!isSimplifiedView()) {
68274
- <symphiq-section-navigation
68275
- [sections]="sections()"
68276
- [viewMode]="viewMode()"
68277
- [embedded]="embedded()"
68278
- [scrollElement]="scrollElement() ?? undefined"
68279
- />
68280
- }
68281
-
68282
- @if (!isSimplifiedView()) {
68283
- <symphiq-floating-toc
68284
- [sections]="sections()"
68285
- [viewMode]="viewMode()"
68286
- [embedded]="embedded()"
68287
- [scrollElement]="scrollElement() ?? undefined"
68288
- />
68289
- }
68290
-
68291
- <symphiq-floating-back-button
68292
- [viewMode]="viewMode()"
68293
- [embedded]="embedded()"
68294
- />
68295
- </div>
68296
-
68297
- <symphiq-tooltip-container />
68298
- <symphiq-business-analysis-modal
68299
- [isLightMode]="isLightMode()"
68300
- (viewInContextRequested)="handleViewInContext($event)" />
68301
-
68302
- <symphiq-search-modal
68303
- [isLightMode]="isLightMode()"
68304
- [isOpen]="searchService.isSearchOpen()"
68305
- [searchQuery]="searchService.getSearchQuery()"
68306
- [results]="searchService.searchResults()"
68307
- [hasResults]="searchService.hasResults()"
68308
- [selectedIndex]="selectedSearchIndex()"
68309
- [placeholder]="'Search sections, items, and analysis...'"
68310
- (searchChange)="onSearchChange($event)"
68311
- (resultSelected)="onSearchResultSelected($event)"
68312
- (close)="closeSearch()"
68313
- />
68314
-
68315
- <symphiq-view-mode-switcher-modal
68316
- [isOpen]="isViewModeSwitcherOpen()"
68317
- [currentMode]="displayMode()"
68318
- [viewMode]="viewMode()"
68319
- [isLoading]="isViewModeSwitching()"
68320
- (close)="closeViewModeSwitcher()"
68321
- (modeSelected)="handleDisplayModeChange($event)"
68322
- />
68323
- </div>
68092
+ args: [{ selector: 'symphiq-business-analysis-dashboard', standalone: true, imports: [CommonModule, ProfileSectionComponent, SectionNavigationComponent, FloatingTocComponent, FloatingBackButtonComponent, TooltipContainerComponent, SectionDividerComponent, BusinessAnalysisModalComponent, SearchButtonComponent, SearchModalComponent, ViewModeSwitcherModalComponent, JourneyProgressIndicatorComponent, WelcomeBannerComponent, RecommendationsTiledGridComponent, CollapsibleSectionGroupComponent, ContentGenerationProgressWithConfettiComponent, IndeterminateSpinnerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
68093
+ <div [ngClass]="getContainerClasses()">
68094
+ <!-- Scroll Progress Bar (fixed at top) -->
68095
+ <div [class]="embedded() ? 'sticky top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30' : 'fixed top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30'">
68096
+ <div
68097
+ [style.width.%]="scrollProgress()"
68098
+ [ngClass]="isLightMode() ? 'bg-gradient-to-r from-blue-500 to-purple-500' : 'bg-gradient-to-r from-blue-400 to-purple-400'"
68099
+ class="h-full transition-all duration-200 ease-out">
68100
+ </div>
68101
+ </div>
68102
+
68103
+ <div class="animated-bubbles" [class.light-mode]="isLightMode()" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none;"></div>
68104
+
68105
+ <div class="relative z-[51]">
68106
+ <header [ngClass]="getHeaderClasses()" class="sticky top-0 z-50">
68107
+ <!-- Expanded Header (default state) -->
68108
+ <div
68109
+ class="transition-all duration-300 ease-in-out overflow-hidden"
68110
+ [class.max-h-0]="headerScrollService.isScrolled()"
68111
+ [class.opacity-0]="headerScrollService.isScrolled()"
68112
+ [class.max-h-96]="!headerScrollService.isScrolled()"
68113
+ [class.opacity-100]="!headerScrollService.isScrolled()">
68114
+ <div
68115
+ class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"
68116
+ [class.pointer-events-none]="headerScrollService.isScrolled()"
68117
+ [class.pointer-events-auto]="!headerScrollService.isScrolled()">
68118
+ <div class="flex items-center justify-between">
68119
+ <div>
68120
+ <h1 [ngClass]="getMainTitleClasses()">
68121
+ {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68122
+ </h1>
68123
+ <p [ngClass]="getSubtitleClasses()">
68124
+ Business Profile & Analysis
68125
+ </p>
68126
+ </div>
68127
+ @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68128
+ <div class="flex items-center gap-2">
68129
+ <symphiq-search-button
68130
+ [isLightMode]="isLightMode()"
68131
+ (searchClick)="openSearch()"
68132
+ />
68133
+ <button
68134
+ type="button"
68135
+ (click)="openViewModeSwitcher()"
68136
+ [ngClass]="getViewModeButtonClasses()"
68137
+ class="cursor-pointer flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68138
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68139
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68140
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68141
+ </svg>
68142
+ <span>{{ displayModeLabel() }}</span>
68143
+ </button>
68144
+ </div>
68145
+ }
68146
+ </div>
68147
+ </div>
68148
+ </div>
68149
+
68150
+ <!-- Condensed Header (scrolled state) -->
68151
+ <div
68152
+ class="transition-all duration-300 ease-in-out overflow-hidden"
68153
+ [class.max-h-0]="!headerScrollService.isScrolled()"
68154
+ [class.opacity-0]="!headerScrollService.isScrolled()"
68155
+ [class.max-h-20]="headerScrollService.isScrolled()"
68156
+ [class.opacity-100]="headerScrollService.isScrolled()">
68157
+ <div
68158
+ class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3"
68159
+ [class.pointer-events-none]="!headerScrollService.isScrolled()"
68160
+ [class.pointer-events-auto]="headerScrollService.isScrolled()">
68161
+ <div class="flex items-center justify-between">
68162
+ <div class="flex-1 min-w-0 mr-4">
68163
+ <h1 [ngClass]="isLightMode() ? 'text-xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent truncate' : 'text-xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent truncate'">
68164
+ {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68165
+ </h1>
68166
+ </div>
68167
+ <div class="flex items-center gap-4">
68168
+ @if (!isSimplifiedView()) {
68169
+ <div class="flex items-center gap-2 text-sm flex-shrink-0">
68170
+ <span [ngClass]="isLightMode() ? 'text-slate-600 font-medium' : 'text-slate-400 font-medium'" class="transition-opacity duration-300" [class.opacity-0]="sectionTitleFading()" [class.opacity-100]="!sectionTitleFading()">
68171
+ {{ currentSectionTitle() }}
68172
+ </span>
68173
+ @if (currentSubsectionTitle()) {
68174
+ <span [ngClass]="isLightMode() ? 'text-slate-400' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">›</span>
68175
+ <span [ngClass]="isLightMode() ? 'text-slate-500' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">
68176
+ {{ currentSubsectionTitle() }}
68177
+ </span>
68178
+ }
68179
+ </div>
68180
+ }
68181
+ @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68182
+ <symphiq-search-button
68183
+ [isLightMode]="isLightMode()"
68184
+ [minimized]="true"
68185
+ (searchClick)="openSearch()"
68186
+ />
68187
+ <button
68188
+ type="button"
68189
+ (click)="openViewModeSwitcher()"
68190
+ [ngClass]="getViewModeButtonClasses()"
68191
+ class="cursor-pointer flex items-center gap-2 px-2 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68192
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68193
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68194
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68195
+ </svg>
68196
+ </button>
68197
+ }
68198
+ </div>
68199
+ </div>
68200
+ </div>
68201
+ </div>
68202
+ </header>
68203
+
68204
+ <main class="relative">
68205
+ @if (isLoading()) {
68206
+ <!-- Pure Loading State -->
68207
+ <div class="flex items-center justify-center min-h-[60vh]">
68208
+ <symphiq-indeterminate-spinner
68209
+ [viewMode]="viewMode()"
68210
+ size="large"
68211
+ />
68212
+ </div>
68213
+ } @else if (isContentGenerating()) {
68214
+ <!-- Journey Progress Banner (always show when not onboarded) -->
68215
+ @if (!isOnboarded()) {
68216
+ <symphiq-journey-progress-indicator
68217
+ [viewMode]="viewMode()"
68218
+ [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68219
+ [showNextStepAction]="false"
68220
+ [forDemo]="forDemo()"
68221
+ [maxAccessibleStepId]="maxAccessibleStepId()"
68222
+ (stepClick)="stepClick.emit($event)"
68223
+ (nextStepClick)="nextStepClick.emit()"
68224
+ />
68225
+ }
68226
+
68227
+ <!-- Content Generation Progress Component -->
68228
+ <symphiq-content-generation-progress-with-confetti
68229
+ [viewMode]="viewMode()"
68230
+ [itemStatus]="itemStatus()"
68231
+ [currentStatus]="profile()?.selfContentStatus"
68232
+ [confettiIntensity]="'celebration'"
68233
+ [title]="'We are generating a new Business Analysis for ' + (currentProfile()?.profileStructured?.businessName || 'your business') + '.'"
68234
+ [subtitle]="'It will appear here when ready. You can check back later as this will take a few minutes to complete.'"
68235
+ />
68236
+ } @else {
68237
+ @if (isSimplifiedView()) {
68238
+ <!-- Journey Progress Banner - Full Width Sticky (only show when not onboarded) -->
68239
+ @if (!isOnboarded()) {
68240
+ <symphiq-journey-progress-indicator
68241
+ [viewMode]="viewMode()"
68242
+ [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68243
+ [showNextStepAction]="showNextStepAction()"
68244
+ [forDemo]="forDemo()"
68245
+ [maxAccessibleStepId]="maxAccessibleStepId()"
68246
+ (stepClick)="stepClick.emit($event)"
68247
+ (nextStepClick)="nextStepClick.emit()"
68248
+ />
68249
+ }
68250
+
68251
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
68252
+ <div class="mb-8">
68253
+ <symphiq-welcome-banner
68254
+ [viewMode]="viewMode()"
68255
+ [businessName]="currentProfile()?.profileStructured?.businessName || 'your business'"
68256
+ [isOnboarded]="isOnboarded()"
68257
+ />
68258
+ </div>
68259
+
68260
+ <div class="mb-8">
68261
+ <symphiq-recommendations-tiled-grid
68262
+ [recommendations]="recommendationItems()"
68263
+ [viewMode]="viewMode()"
68264
+ (viewMoreClick)="openRecommendationDetailsModal($event)"
68265
+ />
68266
+ </div>
68267
+
68268
+ <div>
68269
+ <symphiq-collapsible-section-group
68270
+ [sections]="nonRecommendationSections()"
68271
+ [viewMode]="viewMode()"
68272
+ />
68273
+ </div>
68274
+ </div>
68275
+ } @else {
68276
+ @for (section of sections(); track trackBySectionId($index, section); let idx = $index; let last = $last) {
68277
+ <symphiq-profile-section
68278
+ [section]="section"
68279
+ [viewMode]="viewMode()"
68280
+ [forceExpanded]="!isCompactView()"
68281
+ />
68282
+ @if (!last) {
68283
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
68284
+ <symphiq-section-divider
68285
+ [viewMode]="viewMode()"
68286
+ [subsections]="sections()[idx + 1].subsections || []" />
68287
+ </div>
68288
+ }
68289
+ }
68290
+ }
68291
+ }
68292
+ </main>
68293
+
68294
+ @if (!isSimplifiedView()) {
68295
+ <symphiq-section-navigation
68296
+ [sections]="sections()"
68297
+ [viewMode]="viewMode()"
68298
+ [embedded]="embedded()"
68299
+ [scrollElement]="scrollElement() ?? undefined"
68300
+ />
68301
+ }
68302
+
68303
+ @if (!isSimplifiedView()) {
68304
+ <symphiq-floating-toc
68305
+ [sections]="sections()"
68306
+ [viewMode]="viewMode()"
68307
+ [embedded]="embedded()"
68308
+ [scrollElement]="scrollElement() ?? undefined"
68309
+ />
68310
+ }
68311
+
68312
+ <symphiq-floating-back-button
68313
+ [viewMode]="viewMode()"
68314
+ [embedded]="embedded()"
68315
+ />
68316
+ </div>
68317
+
68318
+ <symphiq-tooltip-container />
68319
+ <symphiq-business-analysis-modal
68320
+ [isLightMode]="isLightMode()"
68321
+ (viewInContextRequested)="handleViewInContext($event)" />
68322
+
68323
+ <symphiq-search-modal
68324
+ [isLightMode]="isLightMode()"
68325
+ [isOpen]="searchService.isSearchOpen()"
68326
+ [searchQuery]="searchService.getSearchQuery()"
68327
+ [results]="searchService.searchResults()"
68328
+ [hasResults]="searchService.hasResults()"
68329
+ [selectedIndex]="selectedSearchIndex()"
68330
+ [placeholder]="'Search sections, items, and analysis...'"
68331
+ (searchChange)="onSearchChange($event)"
68332
+ (resultSelected)="onSearchResultSelected($event)"
68333
+ (close)="closeSearch()"
68334
+ />
68335
+
68336
+ <symphiq-view-mode-switcher-modal
68337
+ [isOpen]="isViewModeSwitcherOpen()"
68338
+ [currentMode]="displayMode()"
68339
+ [viewMode]="viewMode()"
68340
+ [isLoading]="isViewModeSwitching()"
68341
+ (close)="closeViewModeSwitcher()"
68342
+ (modeSelected)="handleDisplayModeChange($event)"
68343
+ />
68344
+ </div>
68324
68345
  `, styles: [":host{display:block}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-highlight{0%,to{transform:scale(1);box-shadow:0 0 #3b82f6b3}50%{transform:scale(1.02);box-shadow:0 0 20px 8px #3b82f64d}}:host ::ng-deep .search-highlight-pulse{animation:pulse-highlight 2s ease-in-out;border-color:#3b82f6!important}\n"] }]
68325
68346
  }], () => [], { embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], profile: [{ type: i0.Input, args: [{ isSignal: true, alias: "profile", required: false }] }], parentHeaderOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentHeaderOffset", required: false }] }], requestedByUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestedByUser", required: false }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], scrollEvent: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollEvent", required: false }] }], scrollElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollElement", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], isOnboarded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOnboarded", required: false }] }], forDemo: [{ type: i0.Input, args: [{ isSignal: true, alias: "forDemo", required: false }] }], maxAccessibleStepId: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxAccessibleStepId", required: false }] }], itemStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemStatus", required: false }] }], stepClick: [{ type: i0.Output, args: ["stepClick"] }], nextStepClick: [{ type: i0.Output, args: ["nextStepClick"] }], onScroll: [{
68326
68347
  type: HostListener,
@@ -73796,7 +73817,7 @@ class PhaseTimelineCardComponent {
73796
73817
  }
73797
73818
  const hierarchy = this.findRecommendationHierarchy(recommendation.id);
73798
73819
  if (hierarchy) {
73799
- this.modalService.openStrategyRecommendationsModal(hierarchy.strategy, hierarchy.objective?.title, hierarchy.goal?.title, this.viewMode(), recommendation.id);
73820
+ this.modalService.openStrategyRecommendationsModal(hierarchy.strategy, hierarchy.objective?.title, hierarchy.goal?.title, this.viewMode(), recommendation.id, hierarchy.goal, hierarchy.objective);
73800
73821
  }
73801
73822
  }
73802
73823
  findRecommendationHierarchy(recommendationId) {
@@ -81804,6 +81825,7 @@ function StrategyRecommendationsModalContentComponent_For_8_Template(rf, ctx) {
81804
81825
  const ctx_r0 = i0.ɵɵnextContext();
81805
81826
  i0.ɵɵclassProp("cursor-pointer", ctx_r0.hasExpandableContent(recommendation_r4));
81806
81827
  i0.ɵɵproperty("ngClass", ctx_r0.cardClasses());
81828
+ i0.ɵɵattribute("id", "recommendation-" + (recommendation_r4.id || $index_r5));
81807
81829
  i0.ɵɵadvance(2);
81808
81830
  i0.ɵɵproperty("ngClass", ctx_r0.iconContainerClasses());
81809
81831
  i0.ɵɵadvance(5);
@@ -81874,6 +81896,12 @@ class StrategyRecommendationsModalContentComponent {
81874
81896
  const recId = this.expandedRecommendationId();
81875
81897
  if (recId) {
81876
81898
  this.expandedRecommendations.set(new Set([recId]));
81899
+ setTimeout(() => {
81900
+ const element = document.getElementById('recommendation-' + recId);
81901
+ if (element) {
81902
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
81903
+ }
81904
+ }, 100);
81877
81905
  }
81878
81906
  }, ...(ngDevMode ? [{ debugName: "expandRecommendationEffect", allowSignalWrites: true }] : [{ allowSignalWrites: true }]));
81879
81907
  this.cardClasses = computed(() => {
@@ -82708,7 +82736,7 @@ class StrategyRecommendationsModalContentComponent {
82708
82736
  i0.ɵɵconditionalCreate(5, StrategyRecommendationsModalContentComponent_Conditional_5_Template, 2, 2, "span", 4);
82709
82737
  i0.ɵɵconditionalCreate(6, StrategyRecommendationsModalContentComponent_Conditional_6_Template, 2, 2, "span", 4);
82710
82738
  i0.ɵɵelementEnd()();
82711
- i0.ɵɵrepeaterCreate(7, StrategyRecommendationsModalContentComponent_For_8_Template, 35, 31, "div", 5, _forTrack0$b);
82739
+ i0.ɵɵrepeaterCreate(7, StrategyRecommendationsModalContentComponent_For_8_Template, 35, 32, "div", 5, _forTrack0$b);
82712
82740
  i0.ɵɵelementEnd();
82713
82741
  } if (rf & 2) {
82714
82742
  let tmp_1_0;
@@ -82775,7 +82803,7 @@ class StrategyRecommendationsModalContentComponent {
82775
82803
 
82776
82804
  <!-- Recommendations Section -->
82777
82805
  @for (recommendation of strategy()?.recommendations; track recommendation.id || $index) {
82778
- <div [ngClass]="cardClasses()" class="rounded p-5 transition-all duration-200 hover:shadow-lg" [class.cursor-pointer]="hasExpandableContent(recommendation)" (click)="hasExpandableContent(recommendation) ? toggleRecommendation($event, recommendation.id || $index) : null">
82806
+ <div [attr.id]="'recommendation-' + (recommendation.id || $index)" [ngClass]="cardClasses()" class="rounded p-5 transition-all duration-200 hover:shadow-lg" [class.cursor-pointer]="hasExpandableContent(recommendation)" (click)="hasExpandableContent(recommendation) ? toggleRecommendation($event, recommendation.id || $index) : null">
82779
82807
  <div class="flex items-start gap-3">
82780
82808
  <div [ngClass]="iconContainerClasses()">
82781
82809
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">