@eui/mobile-core 20.0.2 → 22.0.0-alpha.1

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.
Files changed (196) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/docs/architecture.html +223 -0
  3. package/docs/changelog.html +69 -4
  4. package/docs/components/EuiMUserProfileActionComponent.html +80 -130
  5. package/docs/components/EuiMUserProfileAvatarComponent.html +74 -129
  6. package/docs/components/EuiMUserProfileInfosComponent.html +117 -117
  7. package/docs/components/EuiMUserProfileInfosItemComponent.html +74 -129
  8. package/docs/components/EuimAboutComponent.html +108 -28
  9. package/docs/components/EuimAboutContentLoadingComponent.html +107 -33
  10. package/docs/components/EuimAlertMessageComponent.html +161 -90
  11. package/docs/components/EuimAppComponent.html +105 -27
  12. package/docs/components/EuimAvatarBadgeComponent.html +120 -72
  13. package/docs/components/EuimAvatarComponent.html +123 -121
  14. package/docs/components/EuimAvatarIconComponent.html +74 -129
  15. package/docs/components/EuimAvatarIconSubComponent.html +123 -121
  16. package/docs/components/EuimAvatarImageComponent.html +91 -121
  17. package/docs/components/EuimAvatarTextComponent.html +115 -117
  18. package/docs/components/EuimBadgeComponent.html +121 -43
  19. package/docs/components/EuimCardComponent.html +123 -71
  20. package/docs/components/EuimCardListComponent.html +118 -118
  21. package/docs/components/EuimChangelogComponent.html +131 -128
  22. package/docs/components/EuimChipSelectorComponent.html +257 -184
  23. package/docs/components/EuimDataSummaryColComponent.html +92 -25
  24. package/docs/components/EuimDataSummaryComponent.html +127 -44
  25. package/docs/components/EuimEmptyListPlaceholderComponent.html +176 -156
  26. package/docs/components/EuimHeaderDetailsComponent.html +130 -49
  27. package/docs/components/EuimHelpSupportComponent.html +159 -130
  28. package/docs/components/EuimHelperTextComponent.html +161 -66
  29. package/docs/components/EuimLabelComponent.html +134 -53
  30. package/docs/components/EuimLanguageListComponent.html +185 -31
  31. package/docs/components/EuimLanguageSelectorComponent.html +156 -54
  32. package/docs/components/EuimMediaHeaderComponent.html +137 -52
  33. package/docs/components/EuimMessageComponent.html +130 -47
  34. package/docs/components/EuimMessageTitleComponent.html +92 -25
  35. package/docs/components/EuimMultiselectComponent.html +160 -131
  36. package/docs/components/EuimMultiselectFilterComponent.html +103 -123
  37. package/docs/components/EuimMultiselectInfoComponent.html +91 -125
  38. package/docs/components/EuimMultiselectListComponent.html +85 -122
  39. package/docs/components/EuimMultiselectToolbarComponent.html +126 -134
  40. package/docs/components/EuimNotificationItemComponent.html +121 -43
  41. package/docs/components/EuimOpenSourceLicencesComponent.html +127 -137
  42. package/docs/components/EuimPdfViewerComponent.html +214 -141
  43. package/docs/components/EuimScrollerXComponent.html +78 -130
  44. package/docs/components/EuimSidebarComponent.html +125 -114
  45. package/docs/components/EuimSidebarContentComponent.html +151 -124
  46. package/docs/components/EuimSkeletonListComponent.html +127 -42
  47. package/docs/components/EuimSkeletonListItemComponent.html +159 -56
  48. package/docs/components/EuimSlideInfoScreenComponent.html +74 -129
  49. package/docs/components/EuimSliderInfoScreenComponent.html +247 -174
  50. package/docs/components/EuimSpinnerComponent.html +131 -119
  51. package/docs/components/EuimSpinnerDescriptionComponent.html +74 -129
  52. package/docs/components/EuimSpinnerMessageComponent.html +74 -129
  53. package/docs/components/EuimToolbarActionItemsComponent.html +74 -129
  54. package/docs/components/EuimToolbarComponent.html +150 -140
  55. package/docs/components/EuimToolbarDatepickerComponent.html +291 -114
  56. package/docs/components/EuimToolbarQrcodeComponent.html +100 -32
  57. package/docs/components/EuimToolbarTitleComponent.html +121 -43
  58. package/docs/components/EuimUserProfileComponent.html +117 -117
  59. package/docs/dependencies.html +56 -4
  60. package/docs/directives/BaseStatesDirective.html +175 -62
  61. package/docs/directives/EuimAlignCenterDirective.html +92 -23
  62. package/docs/directives/EuimAlignTopDirective.html +92 -23
  63. package/docs/directives/EuimAvatarMainIconDirective.html +73 -23
  64. package/docs/directives/EuimAvatarSubIconDirective.html +73 -23
  65. package/docs/directives/EuimCardImageDirective.html +86 -118
  66. package/docs/directives/EuimChipSelectorItemDirective.html +104 -108
  67. package/docs/directives/EuimDataSummaryColLabelDirective.html +121 -41
  68. package/docs/directives/EuimDataSummaryColValueDirective.html +117 -41
  69. package/docs/directives/EuimDividerDirective.html +118 -42
  70. package/docs/directives/EuimEmptyListPlaceholderIconDirective.html +92 -23
  71. package/docs/directives/EuimEmptyListPlaceholderSubtitleDirective.html +92 -23
  72. package/docs/directives/EuimEmptyListPlaceholderTitleDirective.html +92 -23
  73. package/docs/directives/EuimFooterTransparentDirective.html +92 -23
  74. package/docs/directives/EuimHeaderDetailsIconDirective.html +66 -126
  75. package/docs/directives/EuimHeaderDetailsMetaDirective.html +66 -126
  76. package/docs/directives/EuimHeaderDetailsTitleDirective.html +66 -126
  77. package/docs/directives/EuimListHeaderDirective.html +118 -42
  78. package/docs/directives/EuimListItemNoPaddingsDirective.html +92 -23
  79. package/docs/directives/EuimMediaHeaderCustomContentDirective.html +95 -23
  80. package/docs/directives/EuimMediaHeaderImageDirective.html +92 -23
  81. package/docs/directives/EuimMediaHeaderSubTitleDirective.html +92 -23
  82. package/docs/directives/EuimMediaHeaderTitleDirective.html +66 -126
  83. package/docs/directives/EuimMinWidthDirective.html +105 -29
  84. package/docs/directives/EuimMultiselectAllDirective.html +138 -101
  85. package/docs/directives/EuimMultiselectSelectFieldDirective.html +102 -127
  86. package/docs/directives/EuimReadOnlyFormDirective.html +66 -126
  87. package/docs/directives/EuimReadOnlyFormLabelDirective.html +92 -23
  88. package/docs/directives/EuimReadOnlyFormValueDirective.html +66 -126
  89. package/docs/directives/EuimSidebarFooterNoBordersDirective.html +92 -23
  90. package/docs/directives/EuimSkeletonTextAvatarDirective.html +92 -23
  91. package/docs/directives/EuimSliderInfoScreenContentDirective.html +112 -114
  92. package/docs/directives/EuimSliderInfoScreenSubTitleDirective.html +66 -126
  93. package/docs/directives/EuimSliderInfoScreenTitleDirective.html +66 -126
  94. package/docs/directives/EuimToolbarDatepickerDatetimeDirective.html +122 -43
  95. package/docs/directives/EuimToolbarTransparentDirective.html +140 -54
  96. package/docs/index.html +54 -2
  97. package/docs/injectables/EuimAppService.html +102 -38
  98. package/docs/interfaces/ActionBtnsIconsNames.html +169 -123
  99. package/docs/interfaces/ActionBtnsNames.html +169 -123
  100. package/docs/interfaces/FilteredData.html +138 -92
  101. package/docs/interfaces/HelpAndSupportItem.html +145 -99
  102. package/docs/interfaces/Item.html +504 -458
  103. package/docs/interfaces/MenuItem.html +408 -362
  104. package/docs/interfaces/UIState.html +109 -63
  105. package/docs/js/architecture-graph.js +288 -0
  106. package/docs/js/libs/bootstrap-native.js +4 -2
  107. package/docs/js/libs/jszip.min.js +13 -0
  108. package/docs/js/libs/svg-pan-zoom.min.js +3 -3
  109. package/docs/js/libs/tablesort.min.js +3 -3
  110. package/docs/js/libs/tablesort.number.min.js +3 -3
  111. package/docs/js/libs/vis-network.min.js +78 -0
  112. package/docs/js/menu-wc.js +25 -13
  113. package/docs/js/routes/routes_index.js +1 -0
  114. package/docs/js/routes.js +142 -34
  115. package/docs/js/search/search.js +62 -0
  116. package/docs/js/search/search_index.js +2 -2
  117. package/docs/js/tabs.js +98 -15
  118. package/docs/js/tree.js +44 -7
  119. package/docs/json/EuimAlertMessageComponent.md +1 -1
  120. package/docs/json/EuimAvatarImageComponent.md +1 -1
  121. package/docs/json/EuimCardListComponent.md +1 -1
  122. package/docs/json/EuimChangelogComponent.md +1 -1
  123. package/docs/json/EuimChipSelectorComponent.md +4 -4
  124. package/docs/json/EuimHeaderDetailsComponent.md +1 -1
  125. package/docs/json/EuimHelperTextComponent.md +1 -0
  126. package/docs/json/EuimMultiselectComponent.md +1 -1
  127. package/docs/json/EuimMultiselectToolbarComponent.md +2 -2
  128. package/docs/json/EuimOpenSourceLicencesComponent.md +2 -2
  129. package/docs/json/EuimPdfViewerComponent.md +0 -1
  130. package/docs/json/EuimSidebarContentComponent.md +3 -4
  131. package/docs/json/EuimSliderInfoScreenComponent.md +3 -3
  132. package/docs/json/EuimToolbarComponent.md +1 -1
  133. package/docs/json/EuimToolbarDatepickerComponent.md +5 -4
  134. package/docs/json/EuimToolbarQrcodeComponent.md +1 -1
  135. package/docs/json/HbsRenderService.md +6 -0
  136. package/docs/json/TemplateEditorService.md +6 -0
  137. package/docs/json/TemplatePlaygroundComponent.md +8 -0
  138. package/docs/json/ZipExportService.md +6 -0
  139. package/docs/json/documentation.json +6868 -3891
  140. package/docs/license.html +46 -4
  141. package/docs/llms.txt +1527 -0
  142. package/docs/miscellaneous/typealiases.html +53 -8
  143. package/docs/miscellaneous/variables.html +320 -36
  144. package/docs/modules/EuimAboutModule.html +87 -10
  145. package/docs/modules/EuimAlertMessageModule.html +75 -10
  146. package/docs/modules/EuimAllModule.html +190 -9
  147. package/docs/modules/EuimAppModule.html +75 -10
  148. package/docs/modules/EuimAvatarModule.html +99 -10
  149. package/docs/modules/EuimBadgeModule.html +75 -10
  150. package/docs/modules/EuimCardListModule.html +75 -10
  151. package/docs/modules/EuimCardModule.html +78 -10
  152. package/docs/modules/EuimChipSelectorComponentModule.html +74 -10
  153. package/docs/modules/EuimDataSummaryModule.html +84 -10
  154. package/docs/modules/EuimDividerModule.html +75 -10
  155. package/docs/modules/EuimEmptyListPlaceholderModule.html +90 -10
  156. package/docs/modules/EuimHeaderDetailsModule.html +84 -10
  157. package/docs/modules/EuimLabelModule.html +87 -10
  158. package/docs/modules/EuimLanguageSelectorModule.html +81 -10
  159. package/docs/modules/EuimListHeaderModule.html +75 -10
  160. package/docs/modules/EuimMediaHeaderModule.html +87 -10
  161. package/docs/modules/EuimMessageModule.html +78 -10
  162. package/docs/modules/EuimMultiselectModule.html +93 -10
  163. package/docs/modules/EuimNotificationItemModule.html +75 -10
  164. package/docs/modules/EuimPdfViewerModule.html +75 -10
  165. package/docs/modules/EuimScrollerXComponentModule.html +75 -10
  166. package/docs/modules/EuimSidebarModule.html +78 -10
  167. package/docs/modules/EuimSkeletonListItemModule.html +75 -10
  168. package/docs/modules/EuimSkeletonListModule.html +75 -10
  169. package/docs/modules/EuimSkeletonTextAvatarModule.html +75 -10
  170. package/docs/modules/EuimSliderInfoScreenModule.html +87 -10
  171. package/docs/modules/EuimSpinnerComponentModule.html +81 -10
  172. package/docs/modules/EuimToolbarComponentModule.html +81 -10
  173. package/docs/modules/EuimToolbarDatepickerModule.html +75 -10
  174. package/docs/modules/EuimToolbarQrcodeModule.html +75 -10
  175. package/docs/modules/EuimUserProfileModule.html +87 -10
  176. package/docs/modules.html +44 -2
  177. package/docs/properties.html +45 -3
  178. package/docs/routes.html +228 -0
  179. package/docs/styles/compodoc.css +365 -44
  180. package/docs/styles/dark.css +16 -0
  181. package/docs/template-playground/default-templates.json +192 -0
  182. package/docs/template-playground/hbs-render.service.ts +217 -0
  183. package/docs/template-playground/main.ts +9 -0
  184. package/docs/template-playground/template-editor.service.ts +173 -0
  185. package/docs/template-playground/template-playground.component.ts +614 -0
  186. package/docs/template-playground/template-playground.module.ts +29 -0
  187. package/docs/template-playground/zip-export.service.ts +86 -0
  188. package/docs/template-playground-app/app.js +1389 -0
  189. package/docs/template-playground-app/index.html +462 -0
  190. package/fesm2022/eui-mobile-core.mjs +870 -1214
  191. package/fesm2022/eui-mobile-core.mjs.map +1 -1
  192. package/package.json +12 -11
  193. package/{index.d.ts → types/eui-mobile-core.d.ts} +143 -215
  194. package/types/eui-mobile-core.d.ts.map +1 -0
  195. package/docs/js/libs/vis.min.js +0 -47
  196. package/docs/js/menu-wc_es5.js +0 -40
@@ -0,0 +1,614 @@
1
+ import { Component, OnInit, ViewChild, ElementRef, OnDestroy } from '@angular/core';
2
+ import { HttpClient } from '@angular/common/http';
3
+ import { TemplateEditorService } from './template-editor.service';
4
+ import { ZipExportService } from './zip-export.service';
5
+ import { HbsRenderService } from './hbs-render.service';
6
+
7
+ interface Template {
8
+ name: string;
9
+ path: string;
10
+ type: 'template' | 'partial';
11
+ }
12
+
13
+ interface Session {
14
+ sessionId: string;
15
+ success: boolean;
16
+ message: string;
17
+ }
18
+
19
+ interface CompoDocConfig {
20
+ hideGenerator?: boolean;
21
+ disableSourceCode?: boolean;
22
+ disableGraph?: boolean;
23
+ disableCoverage?: boolean;
24
+ disablePrivate?: boolean;
25
+ disableProtected?: boolean;
26
+ disableInternal?: boolean;
27
+ disableLifeCycleHooks?: boolean;
28
+ disableConstructors?: boolean;
29
+ disableRoutesGraph?: boolean;
30
+ disableSearch?: boolean;
31
+ disableDependencies?: boolean;
32
+ disableProperties?: boolean;
33
+ disableDomTree?: boolean;
34
+ disableTemplateTab?: boolean;
35
+ disableStyleTab?: boolean;
36
+ disableMainGraph?: boolean;
37
+ disableFilePath?: boolean;
38
+ disableOverview?: boolean;
39
+ hideDarkModeToggle?: boolean;
40
+ minimal?: boolean;
41
+ customFavicon?: string;
42
+ includes?: string;
43
+ includesName?: string;
44
+ }
45
+
46
+ @Component({
47
+ selector: 'template-playground-root',
48
+ template: `
49
+ <div class="template-playground">
50
+ <div class="template-playground-header">
51
+ <h2>Template Playground</h2>
52
+ <div class="template-playground-status">
53
+ <span *ngIf="sessionId" class="session-info">Session: {{sessionId.substring(0, 8)}}...</span>
54
+ <span *ngIf="saving" class="saving-indicator">Saving...</span>
55
+ <span *ngIf="lastSaved" class="last-saved">Last saved: {{lastSaved | date:'short'}}</span>
56
+ </div>
57
+ <div class="template-playground-actions">
58
+ <button class="btn btn-secondary" (click)="toggleConfigPanel()">⚙️ Config</button>
59
+ <button class="btn btn-primary" (click)="resetToDefault()">Reset to Default</button>
60
+ <button class="btn btn-success" (click)="exportZip()">Download Templates</button>
61
+ </div>
62
+ </div>
63
+
64
+ <!-- Configuration Panel -->
65
+ <div class="config-panel" [class.collapsed]="!showConfigPanel">
66
+ <h3>CompoDoc Configuration</h3>
67
+ <div class="config-options">
68
+ <label><input type="checkbox" [(ngModel)]="config.hideGenerator" (change)="updateConfig()"> Hide Generator</label>
69
+ <label><input type="checkbox" [(ngModel)]="config.hideDarkModeToggle" (change)="updateConfig()"> Hide Dark Mode Toggle</label>
70
+ <label><input type="checkbox" [(ngModel)]="config.minimal" (change)="updateConfig()"> Minimal Mode</label>
71
+ <label><input type="checkbox" [(ngModel)]="config.disableOverview" (change)="updateConfig()"> Disable Overview</label>
72
+ <label><input type="checkbox" [(ngModel)]="config.disableFilePath" (change)="updateConfig()"> Disable File Path</label>
73
+ <label><input type="checkbox" [(ngModel)]="config.disableSourceCode" (change)="updateConfig()"> Disable Source Code</label>
74
+ <label><input type="checkbox" [(ngModel)]="config.disableGraph" (change)="updateConfig()"> Disable Graph</label>
75
+ <label><input type="checkbox" [(ngModel)]="config.disableMainGraph" (change)="updateConfig()"> Disable Main Graph</label>
76
+ <label><input type="checkbox" [(ngModel)]="config.disableRoutesGraph" (change)="updateConfig()"> Disable Routes Graph</label>
77
+ <label><input type="checkbox" [(ngModel)]="config.disableCoverage" (change)="updateConfig()"> Disable Coverage</label>
78
+ <label><input type="checkbox" [(ngModel)]="config.disableSearch" (change)="updateConfig()"> Disable Search</label>
79
+ <label><input type="checkbox" [(ngModel)]="config.disableDependencies" (change)="updateConfig()"> Disable Dependencies</label>
80
+ <label><input type="checkbox" [(ngModel)]="config.disablePrivate" (change)="updateConfig()"> Disable Private</label>
81
+ <label><input type="checkbox" [(ngModel)]="config.disableProtected" (change)="updateConfig()"> Disable Protected</label>
82
+ <label><input type="checkbox" [(ngModel)]="config.disableInternal" (change)="updateConfig()"> Disable Internal</label>
83
+ <label><input type="checkbox" [(ngModel)]="config.disableLifeCycleHooks" (change)="updateConfig()"> Disable Lifecycle Hooks</label>
84
+ <label><input type="checkbox" [(ngModel)]="config.disableConstructors" (change)="updateConfig()"> Disable Constructors</label>
85
+ <label><input type="checkbox" [(ngModel)]="config.disableProperties" (change)="updateConfig()"> Disable Properties</label>
86
+ <label><input type="checkbox" [(ngModel)]="config.disableDomTree" (change)="updateConfig()"> Disable DOM Tree</label>
87
+ <label><input type="checkbox" [(ngModel)]="config.disableTemplateTab" (change)="updateConfig()"> Disable Template Tab</label>
88
+ <label><input type="checkbox" [(ngModel)]="config.disableStyleTab" (change)="updateConfig()"> Disable Style Tab</label>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="template-playground-body">
93
+ <div class="template-playground-sidebar">
94
+ <div class="template-file-list">
95
+ <h3>Templates</h3>
96
+ <ul class="file-list">
97
+ <li *ngFor="let template of templates; trackBy: trackByName"
98
+ [class.active]="selectedFile === template"
99
+ (click)="selectFile(template)">
100
+ <i class="file-icon ion-document-text"></i>
101
+ {{template.name}}
102
+ <span class="file-type">{{template.type}}</span>
103
+ </li>
104
+ </ul>
105
+
106
+ <div *ngIf="templates.length === 0" class="loading-templates">
107
+ Loading templates...
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <div class="template-playground-main">
113
+ <div class="template-playground-editor">
114
+ <div class="editor-header" *ngIf="selectedFile">
115
+ <h4>{{selectedFile.path}}</h4>
116
+ <span class="file-type-badge">{{selectedFile.type}}</span>
117
+ </div>
118
+ <div #editorContainer class="editor-container"></div>
119
+ </div>
120
+
121
+ <div class="template-playground-preview">
122
+ <div class="preview-header">
123
+ <h4>Live Preview</h4>
124
+ <button class="btn btn-sm btn-secondary" (click)="refreshPreview()">🔄 Refresh</button>
125
+ </div>
126
+ <iframe #previewFrame class="preview-frame" [src]="previewUrl"></iframe>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ `,
132
+ styles: [`
133
+ .template-playground {
134
+ display: flex;
135
+ flex-direction: column;
136
+ height: 100vh;
137
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
138
+ }
139
+
140
+ .template-playground-header {
141
+ display: flex;
142
+ justify-content: space-between;
143
+ align-items: center;
144
+ padding: 1rem 2rem;
145
+ background: #f8f9fa;
146
+ border-bottom: 1px solid #dee2e6;
147
+ }
148
+
149
+ .template-playground-status {
150
+ display: flex;
151
+ align-items: center;
152
+ gap: 1rem;
153
+ font-size: 0.875rem;
154
+ }
155
+
156
+ .session-info {
157
+ color: #6c757d;
158
+ font-family: monospace;
159
+ }
160
+
161
+ .saving-indicator {
162
+ color: #ffc107;
163
+ font-weight: bold;
164
+ }
165
+
166
+ .last-saved {
167
+ color: #28a745;
168
+ }
169
+
170
+ .template-playground-actions {
171
+ display: flex;
172
+ gap: 0.5rem;
173
+ }
174
+
175
+ .config-panel {
176
+ background: #e9ecef;
177
+ padding: 1rem 2rem;
178
+ border-bottom: 1px solid #dee2e6;
179
+ transition: all 0.3s ease;
180
+ max-height: 200px;
181
+ overflow: hidden;
182
+ }
183
+
184
+ .config-panel.collapsed {
185
+ max-height: 0;
186
+ padding: 0 2rem;
187
+ }
188
+
189
+ .config-options {
190
+ display: grid;
191
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
192
+ gap: 0.5rem;
193
+ margin-top: 0.5rem;
194
+ }
195
+
196
+ .config-options label {
197
+ display: flex;
198
+ align-items: center;
199
+ gap: 0.5rem;
200
+ font-size: 0.875rem;
201
+ }
202
+
203
+ .template-playground-body {
204
+ display: flex;
205
+ flex: 1;
206
+ overflow: hidden;
207
+ }
208
+
209
+ .template-playground-sidebar {
210
+ width: 250px;
211
+ background: #f8f9fa;
212
+ border-right: 1px solid #dee2e6;
213
+ overflow-y: auto;
214
+ }
215
+
216
+ .template-file-list {
217
+ padding: 1rem;
218
+ }
219
+
220
+ .template-file-list h3 {
221
+ margin: 0 0 0.5rem 0;
222
+ font-size: 0.875rem;
223
+ font-weight: 600;
224
+ color: #495057;
225
+ text-transform: uppercase;
226
+ letter-spacing: 0.5px;
227
+ }
228
+
229
+ .file-list {
230
+ list-style: none;
231
+ padding: 0;
232
+ margin: 0 0 1.5rem 0;
233
+ }
234
+
235
+ .file-list li {
236
+ display: flex;
237
+ align-items: center;
238
+ padding: 0.5rem;
239
+ cursor: pointer;
240
+ border-radius: 4px;
241
+ font-size: 0.875rem;
242
+ transition: background-color 0.15s ease;
243
+ }
244
+
245
+ .file-list li:hover {
246
+ background: #e9ecef;
247
+ }
248
+
249
+ .file-list li.active {
250
+ background: #007bff;
251
+ color: white;
252
+ }
253
+
254
+ .file-icon {
255
+ margin-right: 0.5rem;
256
+ opacity: 0.7;
257
+ }
258
+
259
+ .file-type {
260
+ margin-left: auto;
261
+ font-size: 0.75rem;
262
+ opacity: 0.7;
263
+ text-transform: uppercase;
264
+ }
265
+
266
+ .loading-templates {
267
+ text-align: center;
268
+ color: #6c757d;
269
+ font-style: italic;
270
+ padding: 2rem;
271
+ }
272
+
273
+ .template-playground-main {
274
+ flex: 1;
275
+ display: flex;
276
+ overflow: hidden;
277
+ }
278
+
279
+ .template-playground-editor {
280
+ width: 50%;
281
+ display: flex;
282
+ flex-direction: column;
283
+ border-right: 1px solid #dee2e6;
284
+ }
285
+
286
+ .editor-header {
287
+ display: flex;
288
+ justify-content: space-between;
289
+ align-items: center;
290
+ padding: 0.75rem 1rem;
291
+ background: #f8f9fa;
292
+ border-bottom: 1px solid #dee2e6;
293
+ }
294
+
295
+ .editor-header h4 {
296
+ margin: 0;
297
+ font-size: 0.875rem;
298
+ font-weight: 600;
299
+ }
300
+
301
+ .file-type-badge {
302
+ background: #6c757d;
303
+ color: white;
304
+ padding: 0.125rem 0.5rem;
305
+ border-radius: 12px;
306
+ font-size: 0.75rem;
307
+ text-transform: uppercase;
308
+ }
309
+
310
+ .editor-container {
311
+ flex: 1;
312
+ position: relative;
313
+ }
314
+
315
+ .template-playground-preview {
316
+ width: 50%;
317
+ display: flex;
318
+ flex-direction: column;
319
+ }
320
+
321
+ .preview-header {
322
+ display: flex;
323
+ justify-content: space-between;
324
+ align-items: center;
325
+ padding: 0.75rem 1rem;
326
+ background: #f8f9fa;
327
+ border-bottom: 1px solid #dee2e6;
328
+ }
329
+
330
+ .preview-header h4 {
331
+ margin: 0;
332
+ font-size: 0.875rem;
333
+ font-weight: 600;
334
+ }
335
+
336
+ .preview-frame {
337
+ flex: 1;
338
+ border: none;
339
+ background: white;
340
+ }
341
+
342
+ .btn {
343
+ padding: 0.375rem 0.75rem;
344
+ border: 1px solid transparent;
345
+ border-radius: 0.25rem;
346
+ font-size: 0.875rem;
347
+ font-weight: 500;
348
+ text-decoration: none;
349
+ cursor: pointer;
350
+ transition: all 0.15s ease;
351
+ }
352
+
353
+ .btn-primary {
354
+ background: #007bff;
355
+ border-color: #007bff;
356
+ color: white;
357
+ }
358
+
359
+ .btn-primary:hover {
360
+ background: #0056b3;
361
+ border-color: #004085;
362
+ }
363
+
364
+ .btn-secondary {
365
+ background: #6c757d;
366
+ border-color: #6c757d;
367
+ color: white;
368
+ }
369
+
370
+ .btn-secondary:hover {
371
+ background: #545b62;
372
+ border-color: #4e555b;
373
+ }
374
+
375
+ .btn-success {
376
+ background: #28a745;
377
+ border-color: #28a745;
378
+ color: white;
379
+ }
380
+
381
+ .btn-success:hover {
382
+ background: #1e7e34;
383
+ border-color: #1c7430;
384
+ }
385
+
386
+ .btn-sm {
387
+ padding: 0.25rem 0.5rem;
388
+ font-size: 0.75rem;
389
+ }
390
+ `]
391
+ })
392
+ export class TemplatePlaygroundComponent implements OnInit, OnDestroy {
393
+ @ViewChild('editorContainer', { static: true }) editorContainer!: ElementRef;
394
+ @ViewChild('previewFrame', { static: true }) previewFrame!: ElementRef;
395
+
396
+ sessionId: string = '';
397
+ templates: Template[] = [];
398
+ selectedFile: Template | null = null;
399
+ config: CompoDocConfig = {};
400
+ showConfigPanel: boolean = false;
401
+ saving: boolean = false;
402
+ lastSaved: Date | null = null;
403
+
404
+ private saveTimeout?: number;
405
+ private readonly SAVE_DELAY = 300; // 300ms debounce
406
+
407
+ get previewUrl(): string {
408
+ return this.sessionId ? `/api/session/${this.sessionId}/docs/` : '';
409
+ }
410
+
411
+ constructor(
412
+ private http: HttpClient,
413
+ private editorService: TemplateEditorService,
414
+ private zipService: ZipExportService,
415
+ private hbsService: HbsRenderService
416
+ ) {}
417
+
418
+ async ngOnInit() {
419
+ try {
420
+ await this.createSession();
421
+ await this.loadSessionTemplates();
422
+ await this.loadSessionConfig();
423
+ this.initializeEditor();
424
+ } catch (error) {
425
+ console.error('Error initializing template playground:', error);
426
+ }
427
+ }
428
+
429
+ ngOnDestroy() {
430
+ if (this.saveTimeout) {
431
+ clearTimeout(this.saveTimeout);
432
+ }
433
+ }
434
+
435
+ private async createSession(): Promise<void> {
436
+ const response = await this.http.post<Session>('/api/session/create', {}).toPromise();
437
+ if (response && response.success) {
438
+ this.sessionId = response.sessionId;
439
+ console.log('Session created:', this.sessionId);
440
+ } else {
441
+ throw new Error('Failed to create session');
442
+ }
443
+ }
444
+
445
+ private async loadSessionTemplates(): Promise<void> {
446
+ if (!this.sessionId) return;
447
+
448
+ const response = await this.http.get<{templates: Template[], success: boolean}>(`/api/session/${this.sessionId}/templates`).toPromise();
449
+ if (response && response.success) {
450
+ this.templates = response.templates;
451
+
452
+ // Auto-select the first template
453
+ if (this.templates.length > 0 && !this.selectedFile) {
454
+ this.selectFile(this.templates[0]);
455
+ }
456
+ }
457
+ }
458
+
459
+ private async loadSessionConfig(): Promise<void> {
460
+ if (!this.sessionId) return;
461
+
462
+ const response = await this.http.get<{config: CompoDocConfig, success: boolean}>(`/api/session/${this.sessionId}/config`).toPromise();
463
+ if (response && response.success) {
464
+ this.config = response.config;
465
+ }
466
+ }
467
+
468
+ initializeEditor() {
469
+ this.editorService.initializeEditor(this.editorContainer.nativeElement);
470
+
471
+ // Set up debounced save on content change
472
+ this.editorService.setOnChangeCallback((content: string) => {
473
+ this.scheduleAutoSave(content);
474
+ });
475
+ }
476
+
477
+ async selectFile(template: Template) {
478
+ this.selectedFile = template;
479
+
480
+ if (!this.sessionId) return;
481
+
482
+ try {
483
+ const response = await this.http.get<{content: string, success: boolean}>(`/api/session/${this.sessionId}/template/${template.path}`).toPromise();
484
+ if (response && response.success) {
485
+ this.editorService.setEditorContent(response.content, template.type === 'template' ? 'handlebars' : 'handlebars');
486
+ }
487
+ } catch (error) {
488
+ console.error('Error loading template:', error);
489
+ }
490
+ }
491
+
492
+ private scheduleAutoSave(content: string): void {
493
+ if (!this.selectedFile || !this.sessionId) return;
494
+
495
+ // Clear existing timeout
496
+ if (this.saveTimeout) {
497
+ clearTimeout(this.saveTimeout);
498
+ }
499
+
500
+ // Set saving indicator
501
+ this.saving = true;
502
+
503
+ // Schedule new save
504
+ this.saveTimeout = window.setTimeout(async () => {
505
+ try {
506
+ await this.saveTemplate(content);
507
+ this.saving = false;
508
+ this.lastSaved = new Date();
509
+ } catch (error) {
510
+ console.error('Error saving template:', error);
511
+ this.saving = false;
512
+ }
513
+ }, this.SAVE_DELAY);
514
+ }
515
+
516
+ private async saveTemplate(content: string): Promise<void> {
517
+ if (!this.selectedFile || !this.sessionId) return;
518
+
519
+ const response = await this.http.post<{success: boolean}>(`/api/session/${this.sessionId}/template/${this.selectedFile.path}`, {
520
+ content
521
+ }).toPromise();
522
+
523
+ if (!response || !response.success) {
524
+ throw new Error('Failed to save template');
525
+ }
526
+ }
527
+
528
+ async updateConfig(): Promise<void> {
529
+ if (!this.sessionId) return;
530
+
531
+ try {
532
+ const response = await this.http.post<{success: boolean}>(`/api/session/${this.sessionId}/config`, {
533
+ config: this.config
534
+ }).toPromise();
535
+
536
+ if (response && response.success) {
537
+ // Config updated, documentation will be regenerated automatically
538
+ }
539
+ } catch (error) {
540
+ console.error('Error updating config:', error);
541
+ }
542
+ }
543
+
544
+ toggleConfigPanel(): void {
545
+ this.showConfigPanel = !this.showConfigPanel;
546
+ }
547
+
548
+ refreshPreview(): void {
549
+ if (this.previewFrame?.nativeElement) {
550
+ this.previewFrame.nativeElement.src = this.previewFrame.nativeElement.src;
551
+ }
552
+ }
553
+
554
+ resetToDefault(): void {
555
+ // Implementation for resetting to default templates
556
+ if (confirm('Are you sure you want to reset all templates to their default values? This action cannot be undone.')) {
557
+ // TODO: Implement reset functionality
558
+ console.log('Reset to default templates');
559
+ }
560
+ }
561
+
562
+ async exportZip(): Promise<void> {
563
+ try {
564
+ if (!this.sessionId) {
565
+ console.error('No active session. Please refresh the page and try again.');
566
+ return;
567
+ }
568
+
569
+ console.log('Creating template package...');
570
+
571
+ // Call server-side ZIP creation endpoint for all templates
572
+ const response = await this.http.post(`/api/session/${this.sessionId}/download-all-templates`, {}, {
573
+ responseType: 'blob',
574
+ observe: 'response'
575
+ }).toPromise();
576
+
577
+ if (!response || !response.body) {
578
+ throw new Error('Failed to create template package');
579
+ }
580
+
581
+ // Get the ZIP file as a blob
582
+ const zipBlob = response.body;
583
+
584
+ // Get filename from response headers or construct it
585
+ const contentDisposition = response.headers.get('Content-Disposition');
586
+ let filename = `compodoc-templates-${this.sessionId}.zip`;
587
+
588
+ if (contentDisposition) {
589
+ const filenameMatch = contentDisposition.match(/filename="([^"]+)"/);
590
+ if (filenameMatch) {
591
+ filename = filenameMatch[1];
592
+ }
593
+ }
594
+
595
+ // Create download link and trigger download
596
+ const url = URL.createObjectURL(zipBlob);
597
+ const a = document.createElement('a');
598
+ a.href = url;
599
+ a.download = filename;
600
+ document.body.appendChild(a);
601
+ a.click();
602
+ document.body.removeChild(a);
603
+ URL.revokeObjectURL(url);
604
+
605
+ console.log('Template package downloaded successfully!');
606
+ } catch (error) {
607
+ console.error('Error downloading template package:', error);
608
+ }
609
+ }
610
+
611
+ trackByName(index: number, item: Template): string {
612
+ return item.name;
613
+ }
614
+ }
@@ -0,0 +1,29 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { BrowserModule } from '@angular/platform-browser';
3
+ import { CommonModule } from '@angular/common';
4
+ import { FormsModule } from '@angular/forms';
5
+ import { HttpClientModule } from '@angular/common/http';
6
+
7
+ import { TemplatePlaygroundComponent } from './template-playground.component';
8
+ import { TemplateEditorService } from './template-editor.service';
9
+ import { ZipExportService } from './zip-export.service';
10
+ import { HbsRenderService } from './hbs-render.service';
11
+
12
+ @NgModule({
13
+ declarations: [
14
+ TemplatePlaygroundComponent
15
+ ],
16
+ imports: [
17
+ BrowserModule,
18
+ CommonModule,
19
+ FormsModule,
20
+ HttpClientModule
21
+ ],
22
+ providers: [
23
+ TemplateEditorService,
24
+ ZipExportService,
25
+ HbsRenderService
26
+ ],
27
+ bootstrap: [TemplatePlaygroundComponent]
28
+ })
29
+ export class TemplatePlaygroundModule { }