@dataclouder/ngx-lessons 0.0.31 → 0.0.33

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 (86) hide show
  1. package/README.md +56 -10
  2. package/fesm2022/dataclouder-ngx-lessons.mjs +292 -81
  3. package/fesm2022/dataclouder-ngx-lessons.mjs.map +1 -1
  4. package/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.d.ts +9 -5
  5. package/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.d.ts +3 -1
  6. package/lib/components/lesson-mini-components/components/lessons.clases.d.ts +1 -0
  7. package/lib/models/simple-agents.d.ts +2 -0
  8. package/lib/services/lesson-ai.service.d.ts +15 -2
  9. package/lib/services/lesson-utils.service.d.ts +10 -1
  10. package/package.json +1 -1
  11. package/public-api.d.ts +1 -0
  12. package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.html +0 -40
  13. package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.scss +0 -120
  14. package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.ts +0 -82
  15. package/src/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.css +0 -1
  16. package/src/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.html +0 -46
  17. package/src/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.ts +0 -52
  18. package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.css +0 -90
  19. package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.html +0 -67
  20. package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.scss +0 -0
  21. package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.ts +0 -356
  22. package/src/lib/components/dc-lessons/dc-lesson-metadata-editor/dc-lesson-metadata-editor.component.css +0 -1
  23. package/src/lib/components/dc-lessons/dc-lesson-metadata-editor/dc-lesson-metadata-editor.component.html +0 -72
  24. package/src/lib/components/dc-lessons/dc-lesson-metadata-editor/dc-lesson-metadata-editor.component.ts +0 -60
  25. package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.html +0 -23
  26. package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.scss +0 -3
  27. package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.ts +0 -332
  28. package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.html +0 -5
  29. package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.scss +0 -3
  30. package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.ts +0 -14
  31. package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.html +0 -30
  32. package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.scss +0 -17
  33. package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.ts +0 -170
  34. package/src/lib/components/dc-lessons/lessons.component.ts +0 -10
  35. package/src/lib/components/lesson-mini-components/components/ComponentBuilder.ts +0 -82
  36. package/src/lib/components/lesson-mini-components/components/ComponentWithForm.ts +0 -25
  37. package/src/lib/components/lesson-mini-components/components/lesson-dynamic.component.ts +0 -13
  38. package/src/lib/components/lesson-mini-components/components/lessons.clases.ts +0 -220
  39. package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.html +0 -62
  40. package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.scss +0 -15
  41. package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.ts +0 -70
  42. package/src/lib/components/lesson-mini-components/components/selector/selector.component.html +0 -1
  43. package/src/lib/components/lesson-mini-components/components/selector/selector.component.scss +0 -12
  44. package/src/lib/components/lesson-mini-components/components/selector/selector.component.spec.ts +0 -25
  45. package/src/lib/components/lesson-mini-components/components/selector/selector.component.ts +0 -47
  46. package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.html +0 -13
  47. package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.scss +0 -0
  48. package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.ts +0 -40
  49. package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.html +0 -9
  50. package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.scss +0 -3
  51. package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.ts +0 -33
  52. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.html +0 -24
  53. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.scss +0 -15
  54. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.spec.ts +0 -25
  55. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.ts +0 -29
  56. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.html +0 -4
  57. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.scss +0 -8
  58. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.spec.ts +0 -25
  59. package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.ts +0 -61
  60. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.css +0 -3
  61. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.html +0 -9
  62. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.ts +0 -32
  63. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.css +0 -3
  64. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.html +0 -28
  65. package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.ts +0 -30
  66. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.html +0 -18
  67. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.scss +0 -3
  68. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.spec.ts +0 -25
  69. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.ts +0 -25
  70. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.html +0 -15
  71. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.scss +0 -27
  72. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.spec.ts +0 -25
  73. package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.ts +0 -46
  74. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.html +0 -19
  75. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.scss +0 -0
  76. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.ts +0 -27
  77. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.html +0 -14
  78. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.scss +0 -22
  79. package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.ts +0 -51
  80. package/src/lib/models/lessons.pipes.ts +0 -38
  81. package/src/lib/models/models.ts +0 -92
  82. package/src/lib/models/notion.models.ts +0 -43
  83. package/src/lib/services/lesson-ai.service.ts +0 -103
  84. package/src/lib/services/lesson-notion.service.ts +0 -161
  85. package/src/lib/services/lesson-utils.service.ts +0 -181
  86. package/src/public-api.ts +0 -25
@@ -1,356 +0,0 @@
1
- import { Component, ComponentRef, ElementRef, computed, effect, inject, signal, ViewChild, ViewContainerRef } from '@angular/core';
2
- import { ActivatedRoute, Router, ParamMap } from '@angular/router';
3
- import { toSignal } from '@angular/core/rxjs-interop';
4
- import { FormsModule } from '@angular/forms';
5
- import { map } from 'rxjs';
6
-
7
- import BalloonEditor from '@ckeditor/ckeditor5-build-balloon-block';
8
- import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
9
- // PrimeNG
10
- // Removed DialogService, DynamicDialogRef, SpeedDialModule, MenuItem
11
- import { ButtonModule } from 'primeng/button';
12
- import { InputTextModule } from 'primeng/inputtext';
13
- import { SplitterModule } from 'primeng/splitter';
14
- import { TooltipModule } from 'primeng/tooltip';
15
- // Dataclouder
16
- import { AspectType, CropperComponentModal, ResolutionType, StorageImageSettings } from '@dataclouder/ngx-cloud-storage';
17
- import { TOAST_ALERTS_TOKEN, ToastAlertsAbstractService } from '@dataclouder/ngx-core';
18
-
19
- import { DCLessonRendererComponent } from '../dc-lesson-renderer/dc-lesson-renderer.component';
20
- // Added DynamicContentComponent to the import below
21
- import {
22
- LessonComponentEnum,
23
- LessonImage,
24
- ILesson,
25
- LessonComponentInterface,
26
- LESSONS_TOKEN,
27
- DynamicContentComponent,
28
- LessonComponentConfiguration,
29
- } from '../../lesson-mini-components/components/lessons.clases';
30
- import { LessonComponentBuilders } from '../../lesson-mini-components/components/lessons.clases';
31
- import { FlagLanguagePipe, LangDescTranslationPipe } from '../../../models/lessons.pipes';
32
- // Notion types might still be needed if passed/returned, but token injection removed
33
- import { NotionExportType } from '../../../models/notion.models';
34
- // Removed MenuItem import
35
- import { LessonNotionService } from '../../../services/lesson-notion.service';
36
- import { LessonUtilsService } from '../../../services/lesson-utils.service'; // Import the new utils service
37
- import { DCLessonComponentAdderComponent } from '../dc-lesson-component-adder/dc-lesson-component-adder.component'; // Import the component adder
38
- import { DCLessonMetadataEditorComponent } from '../dc-lesson-metadata-editor/dc-lesson-metadata-editor.component'; // Import the metadata editor
39
- import { ComponentBuildData } from '../../lesson-mini-components/components/ComponentBuilder';
40
- import { JsonPipe } from '@angular/common';
41
-
42
- const GradientCss = 'linear-gradient(to bottom,var(--primary-color), rgba(213, 238, 239, 0.31))';
43
-
44
- @Component({
45
- selector: 'dc-lesson-editor',
46
- templateUrl: './dc-lesson-editor.component.html',
47
- styleUrls: ['./dc-lesson-editor.component.css'],
48
- standalone: true,
49
- imports: [
50
- ButtonModule,
51
- CKEditorModule,
52
- CropperComponentModal,
53
- DCLessonRendererComponent,
54
- FormsModule,
55
- InputTextModule,
56
- SplitterModule,
57
- TooltipModule,
58
- // Removed SpeedDialModule
59
- DCLessonComponentAdderComponent, // Add the component adder here
60
- DCLessonMetadataEditorComponent, // Add the metadata editor here
61
- JsonPipe,
62
- ],
63
- providers: [LessonNotionService], // Provide the service here
64
- })
65
- export class DCLessonEditorComponent {
66
- // Services
67
- #activatedRoute = inject(ActivatedRoute); // Re-inject as it's needed for navigation
68
- #lessonNotionService = inject(LessonNotionService);
69
- #lessonUtilsService = inject(LessonUtilsService);
70
- #router = inject(Router);
71
- // Removed #dialogService injection
72
- #lessonService = inject(LESSONS_TOKEN);
73
- #toastService = inject(TOAST_ALERTS_TOKEN);
74
- // ViewChild
75
- @ViewChild('target', { read: ViewContainerRef }) target: ViewContainerRef;
76
- @ViewChild('dhtml', { static: true }) dhtml: ElementRef;
77
- // Signals States
78
- readonly lessonId = toSignal(inject(ActivatedRoute).paramMap.pipe(map((params: ParamMap) => params.get('id'))));
79
- lesson = signal<ILesson | undefined>(undefined); // Initialize as undefined
80
- isCropperVisible = signal(false);
81
- isLoadingLesson = signal(false);
82
- // Removed items signal
83
- // Computed Signals
84
- coverBackground = computed(() => {
85
- const currentLesson = this.lesson();
86
- const coverImage = currentLesson?.media?.images?.find((img: any) => img.type === 'cover') as LessonImage | undefined;
87
- const imageUrl = coverImage?.url || '/assets/images/default_banner.webp';
88
- return `${GradientCss}, url("${imageUrl}")`;
89
- });
90
-
91
- // Computed signal to get dynamic components as an array for easier iteration in the template
92
- readonly dynamicComponentsArray = computed(() => {
93
- const currentLesson = this.lesson();
94
- if (currentLesson?.dynamicComponents) {
95
- return Object.values(currentLesson.dynamicComponents);
96
- }
97
- return []; // Return empty array if no lesson or no dynamic components
98
- });
99
-
100
- // States
101
- public components: { [key: string]: ComponentRef<LessonComponentInterface> } = {}; // Current Dynamic components
102
- public editor = BalloonEditor;
103
- public lessonComponentEnum = LessonComponentEnum;
104
-
105
- public coverStorageSettings: StorageImageSettings = {
106
- path: 'lessons/covers',
107
- fileName: 'cover',
108
- cropSettings: { resizeToWidth: 850, aspectRatio: AspectType.RectangleLarge, resolutions: [ResolutionType.Medium] },
109
- };
110
-
111
- constructor() {
112
- // Removed Speed Dial Items initialization
113
-
114
- // Effect to fetch lesson data when ID changes
115
- effect(async () => {
116
- const id = this.lessonId();
117
- console.log('Lesson ID Signal:', id);
118
- if (id) {
119
- this.isLoadingLesson.set(true); // Start loading
120
- try {
121
- const fetchedLesson = await this.#lessonService.getLesson(id);
122
- if (fetchedLesson) {
123
- this.lesson.set(fetchedLesson);
124
- } else {
125
- this.lesson.set(undefined); // Reset if not found
126
- this.#toastService.warn({ title: 'No se encontró la lección', subtitle: 'Quizá el id es incorrecto' });
127
- // Optional: Navigate away or show a specific "not found" state
128
- // this.#router.navigate(['/path/to/lessons']);
129
- }
130
- } catch (error) {
131
- console.error('Error fetching lesson:', error);
132
- this.lesson.set(undefined); // Reset on error
133
- this.#toastService.error({ title: 'Error al cargar la lección', subtitle: 'Intenta de nuevo más tarde' });
134
- } finally {
135
- this.isLoadingLesson.set(false); // Stop loading
136
- }
137
- } else {
138
- // Handle case for new lesson (ID is null/undefined)
139
- this.lesson.set({ textCoded: `<h1>Nueva lección </h1> <p> Texto aquí</p>`, tags: [] } as ILesson); // Set default new lesson structure
140
- this.isLoadingLesson.set(false); // Ensure loading is off
141
- }
142
- });
143
- }
144
-
145
- /**
146
- * Updates a specific property on the lesson signal.
147
- * Used for ngModelChange events to simulate two-way binding with signals.
148
- * @param property The key of the ILesson property to update.
149
- * @param value The new value for the property.
150
- */
151
- public updateLessonProperty<K extends keyof ILesson>(property: K, value: ILesson[K]): void {
152
- this.lesson.update((currentLesson) => {
153
- if (!currentLesson) return undefined;
154
- return { ...currentLesson, [property]: value };
155
- });
156
- }
157
-
158
- public onTagRemove(tag: any): void {
159
- this.lesson.update((currentLesson) => {
160
- if (!currentLesson) return undefined;
161
- const updatedTags = currentLesson.tags.filter((text: string) => text !== tag.text);
162
- return { ...currentLesson, tags: updatedTags };
163
- });
164
- }
165
-
166
- public onTagAdd(tag: { value: string; input: any }): void {
167
- if (tag.value) {
168
- this.lesson.update((currentLesson) => {
169
- if (!currentLesson) return undefined;
170
- // Avoid duplicate tags if necessary
171
- if (currentLesson.tags.includes(tag.value)) {
172
- return currentLesson;
173
- }
174
- const updatedTags = [...currentLesson.tags, tag.value];
175
- return { ...currentLesson, tags: updatedTags };
176
- });
177
- }
178
- tag.input.nativeElement.value = ''; // Clear input
179
- }
180
-
181
- public async saveLesson(event?: Event): Promise<ILesson | undefined> {
182
- event?.preventDefault();
183
-
184
- const currentLesson = this.lesson();
185
- if (!currentLesson) {
186
- this.#toastService.error({ title: 'Error', subtitle: 'No hay datos de lección para guardar' });
187
- return undefined;
188
- }
189
-
190
- // Clean orphaned components before saving
191
- const lessonToSave = this.#lessonUtilsService.cleanOrphanedComponents(currentLesson);
192
-
193
- // TODO: Implement optimization for saving only changed data.
194
- // This requires comparing lessonToSave with the initially fetched state.
195
- this.isLoadingLesson.set(true); // Indicate saving
196
- try {
197
- // Use the cleaned lesson object for saving
198
- const savedLesson = await this.#lessonService.postLesson(lessonToSave);
199
- const currentId = this.lessonId();
200
-
201
- if (!currentId) {
202
- // It was a new lesson, now it has an ID. Navigate.
203
- this.#toastService.success({ title: 'Se creó la lección', subtitle: 'Éxito' });
204
- // The effect should automatically fetch the lesson again after navigation due to paramMap change.
205
- this.#router.navigate(['../', savedLesson.id], { relativeTo: this.#activatedRoute });
206
- } else {
207
- // It was an existing lesson, update the signal with the potentially updated data from the backend.
208
- this.lesson.set(savedLesson);
209
- this.#toastService.info({ title: 'Se guardaron los cambios en la lección', subtitle: 'Guardado' });
210
- // Call the service method for validation
211
- this.#lessonUtilsService.validateAudios(this.lesson());
212
- }
213
- return savedLesson;
214
- } catch (error: any) {
215
- // Type error
216
- console.error('Error saving lesson:', error);
217
- this.#toastService.error({ title: 'Error al guardar', subtitle: 'No se pudieron guardar los cambios' });
218
- return undefined;
219
- } finally {
220
- this.isLoadingLesson.set(false); // Finish saving indication
221
- }
222
- } // Add missing closing brace for saveLesson
223
-
224
- // Removed openComponentBuilder method
225
-
226
- /**
227
- * Handles the event emitted when a component is added via the adder component.
228
- * @param result The configuration data returned from the component builder dialog. Expected format: { obj: LessonComponentConfiguration }
229
- */
230
- public onComponentAdded(result: ComponentBuildData): void {
231
- debugger;
232
- // Check if result and result.obj.id exist
233
- const newComponent = result?.obj;
234
- if (newComponent?.id) {
235
- console.log('Component builder closed, result received in editor:', newComponent);
236
-
237
- // // Transform LessonComponentConfiguration to DynamicContentComponent
238
- // const dynamicComponentToAdd: DynamicContentComponent = {
239
- // id: componentConfig.id,
240
- // component: componentConfig.component,
241
- // inputs: {
242
- // config: componentConfig, // Pass the original config object as an input named 'config'
243
- // // Add other potential inputs if needed based on component type later
244
- // },
245
- // };
246
-
247
- // Update the lesson signal, adding the transformed component to the dynamicComponents object
248
- this.lesson.update((currentLesson: any) => {
249
- if (!currentLesson) return undefined;
250
-
251
- // Ensure dynamicComponents object exists, initialize if not
252
- const currentDynamicComponents = currentLesson.dynamicComponents || {};
253
-
254
- // Create the updated dynamicComponents object
255
- const updatedDynamicComponents: Record<string, LessonComponentConfiguration<any>> = {
256
- ...currentDynamicComponents,
257
- [newComponent.id]: newComponent, // Use component's id as the key
258
- };
259
-
260
- // Return the updated lesson state
261
- return { ...currentLesson, dynamicComponents: updatedDynamicComponents };
262
- });
263
-
264
- // Optionally save the lesson after adding the component
265
- // this.saveLesson();
266
- }
267
- }
268
-
269
- public openCropper(): void {
270
- // Correctly define openCropper
271
- this.isCropperVisible.set(true);
272
- }
273
-
274
- // isLoadingLesson signal is used directly
275
-
276
- public async generateByAI(): Promise<void> {
277
- const currentId = this.lessonId();
278
- if (!currentId) {
279
- this.#toastService.warn({ title: 'Guardar primero', subtitle: 'Guarda la lección antes de usar IA.' });
280
- return;
281
- }
282
-
283
- this.isLoadingLesson.set(true);
284
- try {
285
- // Ensure latest changes are saved before generating
286
- const savedLesson = await this.saveLesson();
287
- if (!savedLesson) {
288
- // Handle save error - toast is shown in saveLesson
289
- throw new Error('Failed to save before AI generation');
290
- }
291
-
292
- // Call the service method
293
- const updatedLesson = await this.#lessonUtilsService.generateByAI(currentId);
294
-
295
- if (updatedLesson) {
296
- this.lesson.set(updatedLesson); // Update the signal with AI changes from service
297
- // Toast success is handled by the service
298
- } else {
299
- // Toast error is handled by the service
300
- throw new Error('AI generation failed or lesson fetch failed after generation.');
301
- }
302
- } catch (error: any) {
303
- // Type error
304
- console.error('Error during AI generation process in component:', error);
305
- // Service handles specific AI error toasts, maybe add a general one here if needed
306
- // this.#toastService.error({ title: 'Error General', subtitle: 'Ocurrió un problema durante el proceso de IA.' });
307
- } finally {
308
- this.isLoadingLesson.set(false); // Stop loading
309
- }
310
- }
311
-
312
- /**
313
- * Handles the image upload event, updates the lesson signal via the service, and saves.
314
- * @param event The image upload event data.
315
- */
316
- public async onImageUploaded(event: any): Promise<void> {
317
- // Call the service to update the signal
318
- this.#lessonUtilsService.uploadCover(this.lesson, event);
319
- // The coverBackground computed signal will update automatically.
320
- // Save the lesson after the signal has been updated
321
- await this.saveLesson();
322
- }
323
-
324
- /**
325
- * Imports lesson content from Notion using the LessonNotionService.
326
- */
327
- public async importFromNotion(): Promise<void> {
328
- // Use the service's loading state or manage locally
329
- this.isLoadingLesson.set(true);
330
- try {
331
- const newContent = await this.#lessonNotionService.importAndLinkLessonFromNotion(this.lesson(), this.lessonId());
332
-
333
- if (newContent !== null) {
334
- // Update the lesson signal's textCoded property
335
- this.updateLessonProperty('textCoded', newContent);
336
- // Toast success is handled within the service now
337
- }
338
- // If newContent is null, the service handled errors/toasts
339
- } finally {
340
- // Ensure loading state is reset regardless of service outcome
341
- // If observing service state: this.isLoadingLesson.set(this.#lessonNotionService.isLoading());
342
- this.isLoadingLesson.set(false); // Keep local loading for now
343
- }
344
- }
345
-
346
- /**
347
- * Calls the LessonNotionService to improve the lesson using AI based on Notion content.
348
- */
349
- public async improveNotionWithAI(): Promise<void> {
350
- await this.#lessonNotionService.improveLessonWithNotionAI(this.lesson());
351
- }
352
-
353
- public showComponentDetails(data: any) {
354
- alert('showComponentDetails' + JSON.stringify(data));
355
- }
356
- }
@@ -1 +0,0 @@
1
- /* Add any specific styles for the metadata editor here if needed */
@@ -1,72 +0,0 @@
1
- @if (lesson(); as currentLesson) {
2
- <div>
3
- <div>
4
- <div style="display: flex; gap: 10px; padding: 10px">
5
- <p-button label="Guardar" severity="primary" (click)="emitSaveRequest()" />
6
- <p-button label="Importar de Notion" severity="help" (click)="emitImportNotionRequest()" />
7
- <p-button label="Mejorar Notion con AI" severity="help" (click)="emitImproveNotionRequest()" />
8
- </div>
9
-
10
- <!-- Use one-way binding and ngModelChange for signals -->
11
- <div>
12
- <input
13
- pInputText
14
- style="width: 100%"
15
- [ngModel]="currentLesson.title"
16
- (ngModelChange)="onPropertyChange('title', $event)"
17
- type="text"
18
- placeholder="Agrega un título" />
19
- </div>
20
- <div style="margin-top: 4px">
21
- <input
22
- pInputText
23
- style="width: 100%"
24
- [ngModel]="currentLesson.description"
25
- (ngModelChange)="onPropertyChange('description', $event)"
26
- type="text"
27
- placeholder="Agrega una descripción" />
28
- </div>
29
-
30
- <div style="display: flex; align-items: center; margin-top: 10px">
31
- <input
32
- pInputText
33
- style="flex: auto; margin-right: 5px"
34
- [ngModel]="currentLesson.prompt"
35
- (ngModelChange)="onPropertyChange('prompt', $event)"
36
- type="text"
37
- placeholder="Prompt para IA (opcional)" />
38
- <p-button severity="primary" [disabled]="isLoadingLesson()" (click)="emitGenerateAIRequest()"> Generar con IA </p-button>
39
- </div>
40
-
41
- <div style="margin-top: 10px">
42
- <label class="checkbox-container" style="margin-right: 15px">
43
- <input
44
- type="checkbox"
45
- [ngModel]="currentLesson.isPublished"
46
- (ngModelChange)="onPropertyChange('isPublished', $event)"
47
- title="Cuando termines la edición marca esta casilla" />
48
- <span class="checkmark"></span>
49
- Publicada
50
- </label>
51
-
52
- <input
53
- pInputText
54
- [ngModel]="currentLesson.level"
55
- (ngModelChange)="onPropertyChange('level', $event)"
56
- type="number"
57
- placeholder="Nivel"
58
- style="width: 80px" />
59
- </div>
60
-
61
- <!-- Access signal values -->
62
- <div style="margin-top: 10px; font-size: 0.9em; color: var(--text-color-secondary)">
63
- {{ currentLesson.baseLang | flagEmoji }} -> {{ currentLesson.targetLang | flagEmoji }} Lección para hablantes de
64
- {{ currentLesson.baseLang | langDesc : 'es' }} que aprenden
65
- {{ currentLesson.targetLang | langDesc : 'es' }}
66
- </div>
67
- </div>
68
- </div>
69
- } @else {
70
- <!-- Optional: Show a loading state or placeholder if lesson is undefined -->
71
- <p>Cargando datos de la lección...</p>
72
- }
@@ -1,60 +0,0 @@
1
- import { Component, EventEmitter, Input, Output, WritableSignal, signal } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import { ButtonModule } from 'primeng/button';
5
- import { InputTextModule } from 'primeng/inputtext';
6
- import { TooltipModule } from 'primeng/tooltip'; // Added TooltipModule
7
- import { ILesson } from '../../lesson-mini-components/components/lessons.clases';
8
- import { FlagLanguagePipe, LangDescTranslationPipe } from '../../../models/lessons.pipes';
9
-
10
- @Component({
11
- selector: 'dc-lesson-metadata-editor',
12
- standalone: true,
13
- imports: [
14
- CommonModule,
15
- FormsModule,
16
- ButtonModule,
17
- InputTextModule,
18
- TooltipModule, // Added TooltipModule
19
- FlagLanguagePipe, // Added Pipe
20
- LangDescTranslationPipe, // Added Pipe
21
- ],
22
- templateUrl: './dc-lesson-metadata-editor.component.html',
23
- styleUrls: ['./dc-lesson-metadata-editor.component.css'],
24
- })
25
- export class DCLessonMetadataEditorComponent {
26
- // Use signal for input lesson data
27
- @Input({ required: true }) lesson: WritableSignal<ILesson | undefined> = signal(undefined);
28
- @Input({ required: true }) isLoadingLesson: WritableSignal<boolean> = signal(false);
29
-
30
- // Outputs for actions
31
- @Output() saveRequest = new EventEmitter<void>();
32
- @Output() importNotionRequest = new EventEmitter<void>();
33
- @Output() improveNotionRequest = new EventEmitter<void>();
34
- @Output() generateAIRequest = new EventEmitter<void>();
35
-
36
- // Output for property changes
37
- @Output() propertyChange = new EventEmitter<{ property: keyof ILesson; value: any }>();
38
-
39
- // Method to emit property changes, called by ngModelChange in the template
40
- onPropertyChange<K extends keyof ILesson>(property: K, value: ILesson[K]): void {
41
- this.propertyChange.emit({ property, value });
42
- }
43
-
44
- // Methods to emit action requests
45
- emitSaveRequest(): void {
46
- this.saveRequest.emit();
47
- }
48
-
49
- emitImportNotionRequest(): void {
50
- this.importNotionRequest.emit();
51
- }
52
-
53
- emitImproveNotionRequest(): void {
54
- this.improveNotionRequest.emit();
55
- }
56
-
57
- emitGenerateAIRequest(): void {
58
- this.generateAIRequest.emit();
59
- }
60
- }
@@ -1,23 +0,0 @@
1
- <div>
2
- <div #dynamicLesson class="targetclass">
3
- <ng-template #target></ng-template>
4
- </div>
5
- </div>
6
-
7
- <br />
8
- <div style="display: flex; gap: 10px">
9
- @if ((mainForm.controls | keyvalue)?.length) {
10
- <div>
11
- <p-button label="Calificar Lección" icon="pi pi-check-circle" (click)="evaluateForms()" [rounded]="true"></p-button>
12
- </div>
13
- }
14
-
15
- <p-button icon="pi pi-verified" [rounded]="true" (click)="startAI()" label="Repasar con IA" />
16
- </div>
17
- <br /><br />
18
-
19
- @if(chatVisible()) {
20
- <p-drawer header="Conversation" [visible]="chatVisible()" position="bottom" styleClass="app-bottom-overlay">
21
- <dc-chat [agentCard]="agentMasterLesson()" [evaluatorAgentCard]="evaluatorAgentCard()"></dc-chat>
22
- </p-drawer>
23
- }