@dataclouder/ngx-lessons 0.0.30 → 0.0.32
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.
- package/fesm2022/dataclouder-ngx-lessons.mjs +1169 -449
- package/fesm2022/dataclouder-ngx-lessons.mjs.map +1 -1
- package/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.d.ts +2 -2
- package/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.d.ts +11 -0
- package/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.d.ts +39 -38
- package/lib/components/dc-lessons/dc-lesson-metadata-editor/dc-lesson-metadata-editor.component.d.ts +22 -0
- package/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.d.ts +32 -37
- package/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.d.ts +2 -4
- package/lib/components/lesson-mini-components/components/ComponentBuilder.d.ts +7 -2
- package/lib/components/lesson-mini-components/components/lessons.clases.d.ts +17 -42
- package/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.d.ts +13 -0
- package/lib/components/lesson-mini-components/components/speaker/speaker.component.d.ts +12 -0
- package/lib/services/lesson-ai.service.d.ts +18 -0
- package/lib/services/lesson-notion.service.d.ts +35 -0
- package/lib/services/lesson-utils.service.d.ts +34 -0
- package/package.json +3 -2
- package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.html +0 -35
- package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.scss +0 -107
- package/src/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.ts +0 -82
- package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.css +0 -90
- package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.html +0 -105
- package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.scss +0 -0
- package/src/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.ts +0 -318
- package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.html +0 -27
- package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.scss +0 -3
- package/src/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.ts +0 -271
- package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.html +0 -5
- package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.scss +0 -3
- package/src/lib/components/dc-lessons/lesson-form/lesson-form.component.ts +0 -14
- package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.html +0 -30
- package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.scss +0 -17
- package/src/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.ts +0 -170
- package/src/lib/components/dc-lessons/lessons.component.ts +0 -10
- package/src/lib/components/lesson-mini-components/components/ComponentBuilder.ts +0 -74
- package/src/lib/components/lesson-mini-components/components/ComponentWithForm.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/lesson-dynamic.component.ts +0 -13
- package/src/lib/components/lesson-mini-components/components/lessons.clases.ts +0 -254
- package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.html +0 -58
- package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.scss +0 -15
- package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/selector/selector-builder/selector-builder.component.ts +0 -70
- package/src/lib/components/lesson-mini-components/components/selector/selector.component.html +0 -2
- package/src/lib/components/lesson-mini-components/components/selector/selector.component.scss +0 -12
- package/src/lib/components/lesson-mini-components/components/selector/selector.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/selector/selector.component.ts +0 -47
- package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.html +0 -35
- package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.scss +0 -0
- package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.ts +0 -27
- package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.html +0 -7
- package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.scss +0 -3
- package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/speaker/speaker.component.ts +0 -29
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.html +0 -24
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.scss +0 -15
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.ts +0 -29
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.html +0 -4
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.scss +0 -8
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/text-writer/text-writer.component.ts +0 -61
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.css +0 -3
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.html +0 -9
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.ts +0 -32
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.css +0 -3
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.html +0 -28
- package/src/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.ts +0 -30
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.html +0 -18
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.scss +0 -3
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary-builder/verb-summary-builder.component.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.html +0 -15
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.scss +0 -27
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.spec.ts +0 -25
- package/src/lib/components/lesson-mini-components/components/verb-summary/verb-summary.component.ts +0 -46
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.html +0 -19
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.scss +0 -0
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary-builder/word-summary-builder.component.ts +0 -27
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.html +0 -14
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.scss +0 -22
- package/src/lib/components/lesson-mini-components/components/word-summary/word-summary.component.ts +0 -51
- package/src/lib/models/lessons.pipes.ts +0 -38
- package/src/lib/models/models.ts +0 -92
- package/src/lib/models/notion.models.ts +0 -43
- package/src/public-api.ts +0 -25
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<div>
|
|
2
|
-
<!-- <div *ngIf="lesson">
|
|
3
|
-
{lesson.title }}
|
|
4
|
-
<br>
|
|
5
|
-
<img [src]="imageCover" alt="">
|
|
6
|
-
</div> -->
|
|
7
|
-
|
|
8
|
-
<div #dynamicLesson class="targetclass">
|
|
9
|
-
<ng-template #target></ng-template>
|
|
10
|
-
</div>
|
|
11
|
-
</div>
|
|
12
|
-
|
|
13
|
-
<br />
|
|
14
|
-
<div style="display: flex; gap: 10px">
|
|
15
|
-
<div *ngIf="(mainForm.controls | keyvalue)?.length">
|
|
16
|
-
<p-button label="Calificar Lección" icon="pi pi-check-circle" (click)="evaluateForms()" [rounded]="true"></p-button>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<p-button icon="pi pi-verified" [rounded]="true" (click)="startAI()" label="Repasar con IA" />
|
|
20
|
-
</div>
|
|
21
|
-
<br /><br />
|
|
22
|
-
|
|
23
|
-
@if(chatVisible) {
|
|
24
|
-
<p-drawer header="Conversation" [(visible)]="chatVisible" position="bottom" styleClass="app-bottom-overlay">
|
|
25
|
-
<dc-chat [agentCard]="agentMasterLesson" [evaluatorAgentCard]="evaluatorAgentCard"></dc-chat>
|
|
26
|
-
</p-drawer>
|
|
27
|
-
}
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import { Component, ComponentRef, ElementRef, Inject, Input, OnInit, Renderer2, ViewChild, ViewContainerRef } from '@angular/core';
|
|
2
|
-
import { UntypedFormGroup, Validators } from '@angular/forms';
|
|
3
|
-
import { ActivatedRoute } from '@angular/router';
|
|
4
|
-
import { NgIf, KeyValuePipe } from '@angular/common';
|
|
5
|
-
|
|
6
|
-
import { ButtonModule } from 'primeng/button';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
getLessonComponentClass,
|
|
10
|
-
ILesson,
|
|
11
|
-
LangCodeDescription,
|
|
12
|
-
LessonComponentConfiguration,
|
|
13
|
-
LessonComponentsType,
|
|
14
|
-
LESSONS_TOKEN,
|
|
15
|
-
LessonsAbstractService,
|
|
16
|
-
} from '../../lesson-mini-components/components/lessons.clases';
|
|
17
|
-
|
|
18
|
-
import { TOAST_ALERTS_TOKEN, ToastAlertsAbstractService } from '@dataclouder/ngx-core';
|
|
19
|
-
import { LessonComponentInterface } from '../../lesson-mini-components/components/lessons.clases';
|
|
20
|
-
import { ComponentWithForm } from '../../lesson-mini-components/components/ComponentWithForm';
|
|
21
|
-
import {
|
|
22
|
-
CONVERSATION_AI_TOKEN,
|
|
23
|
-
AgentCardsAbstractService,
|
|
24
|
-
DCConversationPromptBuilderService,
|
|
25
|
-
DCChatComponent,
|
|
26
|
-
IAgentCard,
|
|
27
|
-
ConversationType,
|
|
28
|
-
TextEngines,
|
|
29
|
-
IMiniAgentCard,
|
|
30
|
-
} from '@dataclouder/ngx-agent-cards';
|
|
31
|
-
|
|
32
|
-
import { DrawerModule } from 'primeng/drawer';
|
|
33
|
-
|
|
34
|
-
// TODO: i need strategy to create prompt dinamically dpending on user language and level.
|
|
35
|
-
const DefaultLessonAgentCard: IAgentCard = {
|
|
36
|
-
conversationSettings: {
|
|
37
|
-
conversationType: ConversationType.General,
|
|
38
|
-
textEngine: TextEngines.SimpleText,
|
|
39
|
-
autoStart: true,
|
|
40
|
-
},
|
|
41
|
-
characterCard: {
|
|
42
|
-
data: {
|
|
43
|
-
name: 'Lesson Master',
|
|
44
|
-
description: 'You are an AI developed by Polilan Company, you are a lesson master, you are going to help the user to learn english',
|
|
45
|
-
tags: ['lesson', 'master', 'ai'],
|
|
46
|
-
post_history_instructions:
|
|
47
|
-
'Your reply should be always short, 1 or 2 paragraphs at most, and to the point, and you should ask friendly questions all the time',
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
model: { provider: 'google' },
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
@Component({
|
|
54
|
-
selector: 'dc-lesson-renderer',
|
|
55
|
-
templateUrl: './dc-lesson-renderer.component.html',
|
|
56
|
-
styleUrls: ['./dc-lesson-renderer.component.scss'],
|
|
57
|
-
standalone: true,
|
|
58
|
-
imports: [NgIf, KeyValuePipe, ButtonModule, DCChatComponent, DrawerModule],
|
|
59
|
-
})
|
|
60
|
-
export class DCLessonRendererComponent implements OnInit {
|
|
61
|
-
@Input() public lesson: ILesson;
|
|
62
|
-
@Input() public test: boolean;
|
|
63
|
-
|
|
64
|
-
@ViewChild('dynamicLesson', { static: true }) dynamicLesson: ElementRef;
|
|
65
|
-
|
|
66
|
-
public lessonId: string = this.activatedRoute.snapshot.paramMap.get('id');
|
|
67
|
-
public dataText: string = `<h1>Nueva lección </h1> <p> Texto aquí</p>`;
|
|
68
|
-
public components: { [key: string]: ComponentRef<LessonComponentInterface> } = {};
|
|
69
|
-
public mainForm: UntypedFormGroup = new UntypedFormGroup({});
|
|
70
|
-
public imageCover: string;
|
|
71
|
-
|
|
72
|
-
public chatVisible: boolean = false;
|
|
73
|
-
|
|
74
|
-
constructor(
|
|
75
|
-
private renderer: Renderer2,
|
|
76
|
-
private viewContainerRef: ViewContainerRef,
|
|
77
|
-
private activatedRoute: ActivatedRoute,
|
|
78
|
-
@Inject(TOAST_ALERTS_TOKEN) private toastrService: ToastAlertsAbstractService,
|
|
79
|
-
@Inject(LESSONS_TOKEN) private lessonService: LessonsAbstractService,
|
|
80
|
-
@Inject(CONVERSATION_AI_TOKEN) private agentCardsService: AgentCardsAbstractService,
|
|
81
|
-
private conversationBuilder: DCConversationPromptBuilderService, // private userService: UserService,
|
|
82
|
-
) {}
|
|
83
|
-
|
|
84
|
-
ngOnInit(): void {
|
|
85
|
-
this.initLesson();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public async initLesson() {
|
|
89
|
-
await this.getLessonIfId();
|
|
90
|
-
this.renderLesson();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public async getLessonIfId() {
|
|
94
|
-
if (this.lesson) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (!this.lessonId) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
this.dataText = `<h1>Cargando </h1> <p>...</p>`;
|
|
102
|
-
this.lesson = await this.lessonService.getLesson(this.lessonId);
|
|
103
|
-
console.log('lesson', this.lesson);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
private renderLesson(): void {
|
|
107
|
-
this.imageCover = this.lesson.media?.images?.find((img) => img.type === 'cover')?.url;
|
|
108
|
-
|
|
109
|
-
console.log('imageCover', this.imageCover);
|
|
110
|
-
// Pasos para renderizar,
|
|
111
|
-
// 0) Usar la expresión regular para sustitur los componentes por un span con un id
|
|
112
|
-
// 1) En el mismo proceso de remplazar se contruyen dinamicamente los componentes
|
|
113
|
-
// 2) Agregar componentes al DOM en su respectivo spanid
|
|
114
|
-
|
|
115
|
-
// TODO Optimización, es posible agregar el componente al DOM en el mismo paso en que se crea el span?
|
|
116
|
-
|
|
117
|
-
const r1 = new RegExp('~(.+?)~', 'g');
|
|
118
|
-
let count = 0;
|
|
119
|
-
this.components = {}; //Si se destruye la lección, se destruyen todos los componentes dinamicis? tODO necesito reiniciar?
|
|
120
|
-
|
|
121
|
-
const lessonHtml = this.lesson.textCoded.replace(r1, (_matching, jsonCoded) => {
|
|
122
|
-
const componentName = `dynamicComp${count}`;
|
|
123
|
-
count++;
|
|
124
|
-
const componentRef = this.createComponentReferenceWithJson(jsonCoded);
|
|
125
|
-
if (!componentRef) {
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
this.components[componentName] = componentRef;
|
|
129
|
-
if (componentRef.instance.control) {
|
|
130
|
-
// Algunos componentes tienen formularios, estos se copian en mainForm como un unico control
|
|
131
|
-
this.mainForm.addControl(componentName, componentRef.instance.control);
|
|
132
|
-
this.mainForm.get(componentName).setValidators([Validators.required]);
|
|
133
|
-
}
|
|
134
|
-
return `<span id="${componentName}"></span>`;
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
this.dynamicLesson.nativeElement.innerHTML = lessonHtml;
|
|
138
|
-
|
|
139
|
-
for (let compName of Object.keys(this.components)) {
|
|
140
|
-
// Interpolar componentes dentro del lugar correspondiente
|
|
141
|
-
const elementRef = document.getElementById(compName);
|
|
142
|
-
this.addComponentToNode(this.components[compName], elementRef);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private addComponentToNode(componentRef: ComponentRef<LessonComponentInterface>, nodeDOM: any) {
|
|
147
|
-
this.renderer.appendChild(nodeDOM, componentRef.location.nativeElement);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
private createComponentReferenceWithJson(json: string): ComponentRef<LessonComponentInterface> {
|
|
151
|
-
const lessonCodedConfig: LessonComponentConfiguration = JSON.parse(json);
|
|
152
|
-
|
|
153
|
-
let componentConfig;
|
|
154
|
-
if (this.lesson.components && lessonCodedConfig.id) {
|
|
155
|
-
// TODO: retomar, Creo que esta linea es para reutilziar los componentes por id, pero si no tiene,
|
|
156
|
-
componentConfig = this.lesson.components.find((comp) => comp.id === lessonCodedConfig.id);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const LessonClass = getLessonComponentClass(<LessonComponentsType>lessonCodedConfig.component);
|
|
160
|
-
|
|
161
|
-
if (!LessonClass) {
|
|
162
|
-
console.error('No existe este componente, revisa el codigo insertado' + json);
|
|
163
|
-
// throw new Error('No existe este com revisa el codigo insertado');
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const componentRef = this.viewContainerRef.createComponent<LessonComponentInterface>(LessonClass);
|
|
168
|
-
componentRef.instance.config = componentConfig || lessonCodedConfig;
|
|
169
|
-
return componentRef;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public async evaluateForms() {
|
|
173
|
-
if (!this.mainForm.valid) {
|
|
174
|
-
for (let controlName of Object.keys(this.mainForm.controls)) {
|
|
175
|
-
this.components[controlName].instance.validate();
|
|
176
|
-
}
|
|
177
|
-
this.toastrService.warn({ subtitle: 'Por favor completa todos los formularios', title: 'Espera' });
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const rates = { correct: 0, incorrect: 0, score: 0 };
|
|
182
|
-
|
|
183
|
-
for (let controlName of Object.keys(this.mainForm.controls)) {
|
|
184
|
-
const instance = this.components[controlName].instance;
|
|
185
|
-
if (instance instanceof ComponentWithForm) {
|
|
186
|
-
// TODO: quizá no necesito validar instanceof ComponentWithForm ya que se garantiza que todo en mainform tiene un control.
|
|
187
|
-
try {
|
|
188
|
-
const result = instance.evaluate();
|
|
189
|
-
if (result) {
|
|
190
|
-
rates.correct++;
|
|
191
|
-
} else {
|
|
192
|
-
rates.incorrect++;
|
|
193
|
-
}
|
|
194
|
-
} catch (err) {
|
|
195
|
-
console.error('Validation method for instance is failing', instance);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (this.test) {
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
rates.score = rates.correct / (rates.correct + rates.incorrect);
|
|
203
|
-
|
|
204
|
-
const status = rates.score > 0.7 ? 'passed' : 'failed';
|
|
205
|
-
|
|
206
|
-
const takenLesson = { lessonId: this.lesson.id, status: status, score: rates.score };
|
|
207
|
-
// TODO: implementar el servicio para guardar la lección tomada
|
|
208
|
-
// await this.lessonService.saveTakenLesson(takenLesson);
|
|
209
|
-
|
|
210
|
-
if (status === 'passed') {
|
|
211
|
-
this.toastrService.success({ subtitle: 'Aprobaste, se guardó tu calificación', title: 'Muy bien' });
|
|
212
|
-
} else {
|
|
213
|
-
this.toastrService.warn({ subtitle: 'Revisa tus respuestas', title: 'Algunas preguntas no son correctas' });
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
public agentMasterLesson: IAgentCard;
|
|
218
|
-
|
|
219
|
-
public evaluatorAgentCard: IMiniAgentCard;
|
|
220
|
-
|
|
221
|
-
public async startAI() {
|
|
222
|
-
// TODO: para refactorizar y utilizar las lecciones en otro componente, voy a necesitar pasar esto al servicio abstracto asi cada aplicación lo implementa.
|
|
223
|
-
const lessonText = this.lessonService.extractTextFromHtml(this.lesson.textCoded);
|
|
224
|
-
|
|
225
|
-
const scenario = `The user is reading lessons through this app interface. They will now talk with you, and you need to evaluate their understanding of the lesson.
|
|
226
|
-
Ask friendly questions throughout the conversation and help them learn English. Here is the lesson text the user just read:
|
|
227
|
-
${lessonText}
|
|
228
|
-
In your next reply, start by greeting the user, asking something about the lesson, and then continue the conversation.`;
|
|
229
|
-
|
|
230
|
-
// const user = this.userService.getUserSnapshot();
|
|
231
|
-
alert('i need to fix this, need to find a way to pass user throug the service not the library, i think i already started something.');
|
|
232
|
-
const user = {} as any;
|
|
233
|
-
const targetLevel = parseInt(user.languageProgress[user.settings.targetLanguage].level);
|
|
234
|
-
|
|
235
|
-
const langTargetDesc = LangCodeDescription[user.settings.targetLanguage];
|
|
236
|
-
const langBaseDesc = LangCodeDescription[user.settings.baseLanguage];
|
|
237
|
-
|
|
238
|
-
let userInformationPrompt = `
|
|
239
|
-
User information: user name is ${user.personalData.firstname} ${user.personalData.lastname}, their native language is ${langBaseDesc},
|
|
240
|
-
and right now is learning ${langTargetDesc}, their current level is ${user.languageProgress[user.settings.targetLanguage].level} out of 5.`;
|
|
241
|
-
|
|
242
|
-
if (targetLevel <= 2) {
|
|
243
|
-
userInformationPrompt += `\nUser is a beginner in english, always reply in ${langBaseDesc}, but during the conversation use simple words in ${langTargetDesc}`;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
console.log('lessonText', lessonText);
|
|
247
|
-
|
|
248
|
-
const lessonAgentCard: IAgentCard = DefaultLessonAgentCard;
|
|
249
|
-
lessonAgentCard.characterCard.data.scenario = scenario;
|
|
250
|
-
lessonAgentCard.characterCard.data.post_history_instructions += `\n${userInformationPrompt}`;
|
|
251
|
-
this.agentMasterLesson = lessonAgentCard;
|
|
252
|
-
|
|
253
|
-
this.evaluatorAgentCard = this.getDefualtLessonEvaluatorAgentCard(lessonText);
|
|
254
|
-
this.chatVisible = true;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
private getDefualtLessonEvaluatorAgentCard(lessonText: string): IMiniAgentCard {
|
|
258
|
-
return {
|
|
259
|
-
expectedResponseType: `interface EvalResult {
|
|
260
|
-
score: number; // Score of the user's response 0 to 3
|
|
261
|
-
feedback: string; // Feedback of the user's understanding of the conversation
|
|
262
|
-
}`,
|
|
263
|
-
messages: [],
|
|
264
|
-
model: { id: 'gpt-4o-mini', provider: 'openai' },
|
|
265
|
-
sources: [lessonText],
|
|
266
|
-
task: `User is reading a taking a lesson, now their are having a conversation,
|
|
267
|
-
you have to evaluate the current conversation, and give a feedback of the user understanding of the lesson,
|
|
268
|
-
this is the lesson: ${lessonText}`,
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Component } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
|
-
|
|
5
|
-
@Component({
|
|
6
|
-
selector: 'dc-lesson-form',
|
|
7
|
-
templateUrl: './lesson-form.component.html',
|
|
8
|
-
styleUrls: ['./lesson-form.component.scss'],
|
|
9
|
-
standalone: true,
|
|
10
|
-
imports: [CommonModule, ReactiveFormsModule],
|
|
11
|
-
})
|
|
12
|
-
export class DCLessonFormComponent {
|
|
13
|
-
// Form implementation will go here
|
|
14
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<dc-filter-bar [customFilters]="customFilters" (onFilterAction)="applyFilterBarEvent($event)"></dc-filter-bar>
|
|
2
|
-
|
|
3
|
-
@if(viewType === 'table') {
|
|
4
|
-
<app-quick-table [columns]="columns" [tableData]="lessons" [actions]="actions" (onAction)="doOrEmitAction($event)"></app-quick-table>
|
|
5
|
-
} @else {
|
|
6
|
-
<div class="lesson-list-container">
|
|
7
|
-
@if (!isLoadingLessons && lessons?.length > 0) { @for (lesson of lessons; track lesson._id) {
|
|
8
|
-
<ng-container
|
|
9
|
-
#outlet="ngComponentOutlet"
|
|
10
|
-
[ngComponentOutlet]="cardComponent"
|
|
11
|
-
[ngComponentOutletInputs]="{
|
|
12
|
-
lesson: lesson,
|
|
13
|
-
isAdmin: isAdmin
|
|
14
|
-
}">
|
|
15
|
-
</ng-container>
|
|
16
|
-
} } @else {
|
|
17
|
-
<p>No se encontraron lecciones disponibles</p>
|
|
18
|
-
}
|
|
19
|
-
</div>
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
<p-paginator
|
|
23
|
-
currentPageReportTemplate="{{ totalRecords }} lecciones"
|
|
24
|
-
[showCurrentPageReport]="true"
|
|
25
|
-
(onPageChange)="onPageChange($event)"
|
|
26
|
-
[first]="paginatorFirst"
|
|
27
|
-
[rows]="paginatorRows"
|
|
28
|
-
[totalRecords]="totalRecords"
|
|
29
|
-
[rowsPerPageOptions]="[10, 20, 30]">
|
|
30
|
-
</p-paginator>
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
height: 100%;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
.lesson-list-container {
|
|
8
|
-
padding: 1rem;
|
|
9
|
-
flex: 1;
|
|
10
|
-
overflow-y: auto;
|
|
11
|
-
min-height: 0; /* This is important for flex containers to respect overflow */
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
p-paginator {
|
|
15
|
-
margin-top: auto;
|
|
16
|
-
padding: 0.5rem 1rem;
|
|
17
|
-
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectorRef, Component, EventEmitter, Inject, Input, OnInit, Output, Type, ViewChildren, QueryList, OnDestroy } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { PaginatorModule } from 'primeng/paginator';
|
|
4
|
-
import { NgComponentOutlet } from '@angular/common';
|
|
5
|
-
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
|
6
|
-
|
|
7
|
-
import { Subscription } from 'rxjs';
|
|
8
|
-
import {
|
|
9
|
-
DCFilterBarComponent,
|
|
10
|
-
ICustomFilter,
|
|
11
|
-
OnActionEvent,
|
|
12
|
-
PaginationBase,
|
|
13
|
-
PColumn,
|
|
14
|
-
QuickTableComponent,
|
|
15
|
-
TOAST_ALERTS_TOKEN,
|
|
16
|
-
ToastAlertsAbstractService,
|
|
17
|
-
} from '@dataclouder/ngx-core';
|
|
18
|
-
|
|
19
|
-
import { LESSONS_TOKEN, LessonsAbstractService } from '../../lesson-mini-components/components/lessons.clases';
|
|
20
|
-
import { DcLessonCardComponent } from '../dc-lesson-card/dc-lesson-card.component';
|
|
21
|
-
import { MenuItem } from 'node_modules/primeng/api/menuitem';
|
|
22
|
-
|
|
23
|
-
const tableViewColumns: PColumn[] = [
|
|
24
|
-
{ field: 'media.images[0].url', header: 'Image', type: 'image' },
|
|
25
|
-
{ field: 'title', header: 'Título' },
|
|
26
|
-
{ field: 'description', header: 'Descripción' },
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
const TableViewActions: MenuItem[] = [
|
|
30
|
-
{ title: 'select', label: 'Select', icon: 'pi pi-check', severity: 'primary' },
|
|
31
|
-
{ title: 'qr', label: 'QR', icon: 'pi pi-qrcode', severity: 'info' },
|
|
32
|
-
{ title: 'edit', label: 'Edit', icon: 'pi pi-pencil', severity: 'info' },
|
|
33
|
-
{ title: 'delete', label: 'Delete', icon: 'pi pi-trash', severity: 'danger' },
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
const returnProperties: Record<string, 0 | 1> = { id: 1, title: 1, assets: 1 };
|
|
37
|
-
|
|
38
|
-
@Component({
|
|
39
|
-
selector: 'dc-lesson-list',
|
|
40
|
-
templateUrl: './dc-lesson-list.component.html',
|
|
41
|
-
styleUrls: ['./dc-lesson-list.component.scss'],
|
|
42
|
-
standalone: true,
|
|
43
|
-
imports: [CommonModule, RouterModule, DCFilterBarComponent, PaginatorModule, NgComponentOutlet, QuickTableComponent],
|
|
44
|
-
})
|
|
45
|
-
export class DCLessonListComponent extends PaginationBase implements OnInit, OnDestroy {
|
|
46
|
-
@Input() public isAdmin: boolean = false;
|
|
47
|
-
@Input() public customCardComponent?: Type<DcLessonCardComponent>;
|
|
48
|
-
@Input() public customFilters: ICustomFilter[] = [];
|
|
49
|
-
@Input() public viewType: 'table' | 'cards' = 'cards';
|
|
50
|
-
|
|
51
|
-
@Input() public override actions: MenuItem[] = TableViewActions;
|
|
52
|
-
|
|
53
|
-
public override columns: PColumn[] = tableViewColumns;
|
|
54
|
-
|
|
55
|
-
@ViewChildren('outlet') outlets!: QueryList<NgComponentOutlet>;
|
|
56
|
-
|
|
57
|
-
public cardComponent: Type<DcLessonCardComponent> = null;
|
|
58
|
-
public cardEventSubs: Subscription[] = [];
|
|
59
|
-
|
|
60
|
-
public lessons: any[] = [];
|
|
61
|
-
public isLoadingLessons = false;
|
|
62
|
-
|
|
63
|
-
constructor(
|
|
64
|
-
private cdr: ChangeDetectorRef,
|
|
65
|
-
public override router: Router,
|
|
66
|
-
public override route: ActivatedRoute,
|
|
67
|
-
@Inject(LESSONS_TOKEN) private lessonsService: LessonsAbstractService,
|
|
68
|
-
@Inject(TOAST_ALERTS_TOKEN) private toastrService: ToastAlertsAbstractService,
|
|
69
|
-
) {
|
|
70
|
-
super(route, router);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
ngOnInit(): void {
|
|
74
|
-
this.filterConfig.returnProps = returnProperties;
|
|
75
|
-
this.cardComponent = this.customCardComponent || DcLessonCardComponent;
|
|
76
|
-
|
|
77
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
public subscribeDinamicInstantToEvents() {
|
|
81
|
-
this.clearcardEventSubs();
|
|
82
|
-
this.subscribeToCardEvents();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
private subscribeToCardEvents() {
|
|
86
|
-
this.outlets.forEach((outlet) => {
|
|
87
|
-
const instance: DcLessonCardComponent = outlet.componentInstance;
|
|
88
|
-
|
|
89
|
-
this.cardEventSubs.push(
|
|
90
|
-
instance.onAction.subscribe((lesson: any) => {
|
|
91
|
-
this.doOrEmitAction(lesson);
|
|
92
|
-
}),
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private clearcardEventSubs() {
|
|
98
|
-
this.cardEventSubs.forEach((sub) => sub.unsubscribe());
|
|
99
|
-
this.cardEventSubs = [];
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
ngOnDestroy() {
|
|
103
|
-
this.clearcardEventSubs();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
public async getPaginatedLessons(paginator: any) {
|
|
107
|
-
try {
|
|
108
|
-
this.lessons = null;
|
|
109
|
-
this.isLoadingLessons = true;
|
|
110
|
-
this.cdr.detectChanges();
|
|
111
|
-
const lessons = await this.lessonsService.getLessons(paginator);
|
|
112
|
-
|
|
113
|
-
this.lessons = lessons['rows'] || lessons;
|
|
114
|
-
this.totalRecords = lessons['count'] || this.lessons.length;
|
|
115
|
-
|
|
116
|
-
console.log('lessons', lessons);
|
|
117
|
-
|
|
118
|
-
setTimeout(() => {
|
|
119
|
-
this.subscribeDinamicInstantToEvents();
|
|
120
|
-
});
|
|
121
|
-
} finally {
|
|
122
|
-
this.isLoadingLessons = false;
|
|
123
|
-
this.cdr.detectChanges();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
public search(searchText: string) {
|
|
128
|
-
this.filterConfig['text'] = searchText;
|
|
129
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
private removeLesson(lesson: any) {
|
|
133
|
-
const response = confirm('¿Estás seguro de querer eliminar esta lección?');
|
|
134
|
-
if (response) {
|
|
135
|
-
this.lessonsService.deleteLesson(lesson._id);
|
|
136
|
-
this.lessons = this.lessons.filter((l) => l._id !== lesson._id);
|
|
137
|
-
this.cdr.detectChanges();
|
|
138
|
-
this.toastrService.success({ title: 'Adios a la lección', subtitle: 'La lección ha sido eliminada correctamente' });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
public newLesson() {
|
|
143
|
-
this.onAction.emit({ action: 'new' });
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
public applyFilterBarEvent(filterEvent: OnActionEvent) {
|
|
147
|
-
if (filterEvent.action == 'changeView') {
|
|
148
|
-
this.viewType = this.viewType === 'table' ? 'cards' : 'table';
|
|
149
|
-
return;
|
|
150
|
-
} else {
|
|
151
|
-
console.log('filterChanged in dc-lesson-list', filterEvent);
|
|
152
|
-
this.filterConfig = filterEvent.item;
|
|
153
|
-
this.filterConfig.returnProps = returnProperties;
|
|
154
|
-
|
|
155
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
protected override loadData(): Promise<void> {
|
|
160
|
-
return this.getPaginatedLessons(this.filterConfig);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
public doOrEmitAction(actionEvent: OnActionEvent) {
|
|
164
|
-
if (actionEvent.action === 'delete') {
|
|
165
|
-
this.removeLesson(actionEvent.item);
|
|
166
|
-
} else {
|
|
167
|
-
this.onAction.emit(actionEvent);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Component } from '@angular/core';
|
|
2
|
-
import { RouterOutlet } from '@angular/router';
|
|
3
|
-
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'app-lessonsv2',
|
|
6
|
-
template: '<router-outlet></router-outlet>',
|
|
7
|
-
standalone: true,
|
|
8
|
-
imports: [RouterOutlet],
|
|
9
|
-
})
|
|
10
|
-
export class LessonsV2Component {}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { Component } from '@angular/core';
|
|
2
|
-
import { FormBuilder, FormControl } from '@angular/forms';
|
|
3
|
-
import { DynamicDialogRef } from 'primeng/dynamicdialog';
|
|
4
|
-
|
|
5
|
-
import { LessonComponentBuilders, LessonComponentConfiguration, LessonComponentEnum, LessonCompSettings } from './lessons.clases';
|
|
6
|
-
|
|
7
|
-
// Create a type that maps the interface to FormControls
|
|
8
|
-
export type LessonCompSettingsForm = {
|
|
9
|
-
[K in keyof Required<LessonCompSettings>]: FormControl<LessonCompSettings[K]>;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
@Component({
|
|
13
|
-
selector: 'app-component-builder',
|
|
14
|
-
template: '<div>no template</div>',
|
|
15
|
-
})
|
|
16
|
-
export class ComponentBuilder {
|
|
17
|
-
constructor(
|
|
18
|
-
protected formBuilder: FormBuilder,
|
|
19
|
-
// protected toastrService: ToastService, // protected ref: NbDialogRef<ComponentBuilder>,
|
|
20
|
-
protected ref: DynamicDialogRef,
|
|
21
|
-
) {}
|
|
22
|
-
|
|
23
|
-
// Sobreescribir si es necesario
|
|
24
|
-
// public formGroup = this.formBuilder.group<LessonCompSettings>({});
|
|
25
|
-
|
|
26
|
-
public formGroup = this.formBuilder.group({
|
|
27
|
-
response: new FormControl<string | null>(null),
|
|
28
|
-
responses: new FormControl<string | null>(null),
|
|
29
|
-
options: this.formBuilder.array([]),
|
|
30
|
-
text: new FormControl<string | null>(null),
|
|
31
|
-
hint: new FormControl<string | null>(null),
|
|
32
|
-
explanation: new FormControl<string | null>(null),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Every component knows its type by comparing agains LessonComponentBuilders
|
|
36
|
-
get questionType(): LessonComponentEnum {
|
|
37
|
-
const self = this;
|
|
38
|
-
|
|
39
|
-
const name = Object.keys(LessonComponentBuilders).find((componentName: any) => {
|
|
40
|
-
const componentClass = LessonComponentBuilders[componentName];
|
|
41
|
-
if (self instanceof componentClass) {
|
|
42
|
-
return componentName;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return <LessonComponentEnum>name;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
private getCode(): string {
|
|
50
|
-
const data = this.formGroup.value;
|
|
51
|
-
// Deleting null values
|
|
52
|
-
Object.keys(data).forEach((key) => {
|
|
53
|
-
if (data[key] === null) {
|
|
54
|
-
delete data[key];
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
const id = Math.random().toString(36).substring(7);
|
|
58
|
-
const code: LessonComponentConfiguration = { id: id, component: this.questionType, settings: { ...data } as unknown as LessonCompSettings };
|
|
59
|
-
return `~${JSON.stringify(code)}~`;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public showCode() {
|
|
63
|
-
const code = this.getCode();
|
|
64
|
-
alert(code);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public async copyToClipboard() {
|
|
68
|
-
const code = this.getCode();
|
|
69
|
-
await navigator.clipboard.writeText(code);
|
|
70
|
-
// this.toastrService.info('Control + V para pegar', 'Se copió al portapapeles');
|
|
71
|
-
// this.ref.close();
|
|
72
|
-
this.ref.close(code);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Component, Input, OnInit } from '@angular/core';
|
|
2
|
-
import { UntypedFormControl } from '@angular/forms';
|
|
3
|
-
|
|
4
|
-
@Component({
|
|
5
|
-
selector: 'app-component-form',
|
|
6
|
-
template: '<div>no template</div>',
|
|
7
|
-
})
|
|
8
|
-
export abstract class ComponentWithForm implements OnInit {
|
|
9
|
-
// @Input() settings: LessonCompSettings;
|
|
10
|
-
|
|
11
|
-
public control: UntypedFormControl = new UntypedFormControl();
|
|
12
|
-
public status: string;
|
|
13
|
-
|
|
14
|
-
ngOnInit(): void {
|
|
15
|
-
this.control.valueChanges.subscribe(() => {
|
|
16
|
-
this.status = 'basic';
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public validate(): void {
|
|
21
|
-
// TODO: generic method to evaluate
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public abstract evaluate(): boolean;
|
|
25
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
import { LessonCompSettings } from './lessons.clases';
|
|
4
|
-
|
|
5
|
-
@Component({
|
|
6
|
-
selector: 'app-lesson-component',
|
|
7
|
-
template: '<div>no template</div>',
|
|
8
|
-
standalone: true,
|
|
9
|
-
})
|
|
10
|
-
// This is the base class for all the components that are going to be used in the lessons.
|
|
11
|
-
export class LessonDynamicComponent {
|
|
12
|
-
@Input() settings: LessonCompSettings = {} as LessonCompSettings;
|
|
13
|
-
}
|