@dataclouder/ngx-lessons 0.1.7 → 0.1.8
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.
|
@@ -3,7 +3,7 @@ import { Pipe, InjectionToken, inject, Input, Component, ChangeDetectionStrategy
|
|
|
3
3
|
import { DatePipe, NgComponentOutlet, KeyValuePipe, CommonModule, SlicePipe } from '@angular/common';
|
|
4
4
|
import * as i1$4 from '@angular/router';
|
|
5
5
|
import { RouterModule, ActivatedRoute, RouterOutlet, RouterLink } from '@angular/router';
|
|
6
|
-
import { EntityCommunicationService, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent, TOAST_ALERTS_TOKEN, EModelQuality, UiStateService, LoadingBarService, LangDescTranslation, FormUtilsService, EntityBaseFormComponent, PromptService,
|
|
6
|
+
import { EntityCommunicationService, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent, TOAST_ALERTS_TOKEN, EModelQuality, UiStateService, LoadingBarService, LangDescTranslation, FormUtilsService, EntityBaseFormComponent, PromptService, DcManageableFormComponent, DcLearnableFormComponent, HttpCoreService, PaginationBase, getSupportedLanguageOptions } from '@dataclouder/ngx-core';
|
|
7
7
|
import * as i1 from '@angular/forms';
|
|
8
8
|
import { FormBuilder, FormControl, FormArray, FormsModule, ReactiveFormsModule, UntypedFormControl, FormGroup, Validators } from '@angular/forms';
|
|
9
9
|
import * as i1$1 from 'primeng/button';
|
|
@@ -37,7 +37,7 @@ import { SplitterModule } from 'primeng/splitter';
|
|
|
37
37
|
import * as i7 from 'primeng/tooltip';
|
|
38
38
|
import { TooltipModule } from 'primeng/tooltip';
|
|
39
39
|
import { ResolutionType, AspectType, AssetsLoaderComponent, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
|
|
40
|
-
import {
|
|
40
|
+
import { USER_DATA_EXCHANGE, EvalResultStringDefinition, SystemPromptType, EDoActionType, ConditionOperator, ConditionType, ConversationEvents, ChatRole, TextEngines, ConversationType, ChatEventType, DCChatComponent, CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
41
41
|
import * as i2$2 from 'primeng/drawer';
|
|
42
42
|
import { DrawerModule } from 'primeng/drawer';
|
|
43
43
|
import { MarkdownComponent, MarkdownService } from 'ngx-markdown';
|
|
@@ -1074,129 +1074,14 @@ Assign a rating from 0 to 3 based on how well the student performs *compared to
|
|
|
1074
1074
|
Provide detailed, constructive feedback that explains the rating. Point out specific strengths and areas for improvement based on their performance *at their given level*. Use examples from the dialog if helpful. Maintain a supportive, encouraging, and educational tone appropriate for a virtual professor guiding a student at their specific stage.
|
|
1075
1075
|
`;
|
|
1076
1076
|
|
|
1077
|
-
// Re-define or import constants if they are not exported from the component file
|
|
1078
|
-
const DEFAULT_LESSON_AGENT_CARD = {
|
|
1079
|
-
conversationSettings: {
|
|
1080
|
-
conversationType: ConversationType.General,
|
|
1081
|
-
textEngine: TextEngines.SimpleText,
|
|
1082
|
-
autoStart: true,
|
|
1083
|
-
},
|
|
1084
|
-
characterCard: {
|
|
1085
|
-
data: {
|
|
1086
|
-
name: 'Lesson Master',
|
|
1087
|
-
description: 'You are an AI developed by Polilan Company, you are a lesson master, you are going to help the user to learn english',
|
|
1088
|
-
tags: ['lesson', 'master', 'ai'],
|
|
1089
|
-
post_history_instructions: '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',
|
|
1090
|
-
},
|
|
1091
|
-
},
|
|
1092
|
-
};
|
|
1093
|
-
const AppRolePlaySkill = `
|
|
1094
|
-
You are an app role play assistant from Polilan App. 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.
|
|
1095
|
-
Ask friendly questions throughout the conversation and help them learn English.
|
|
1096
|
-
`;
|
|
1097
1077
|
const EngagementSkill = `
|
|
1098
|
-
You are an engagement assistant, start by greeting the user, asking something about the lesson, and then continue the conversation. always ask one or two friendly questions.
|
|
1099
|
-
that makes sense for the lesson.
|
|
1078
|
+
You are an engagement assistant, start by greeting the user, asking something about the lesson, and then continue the conversation. always ask one or two friendly questions.
|
|
1079
|
+
that makes sense for the lesson.
|
|
1100
1080
|
`;
|
|
1101
|
-
|
|
1102
|
-
// TODO: probably i need to build in order to add the sources to the task or system.
|
|
1103
|
-
return {
|
|
1104
|
-
expectedResponseType: `interface EvalResult {
|
|
1105
|
-
score: number; // Score of the user's response 0 to 3
|
|
1106
|
-
feedback: string; // Feedback of the user's understanding of the conversation
|
|
1107
|
-
}`,
|
|
1108
|
-
model: { id: 'gpt-4o-mini', provider: 'openai' },
|
|
1109
|
-
task: `User is reading a taking a lesson, now their are having a conversation,
|
|
1110
|
-
you have to evaluate the current conversation, and give a feedback of the user understanding of the lesson,
|
|
1111
|
-
this is the lesson: ${lessonText}`,
|
|
1112
|
-
};
|
|
1113
|
-
}
|
|
1114
|
-
class LessonAIService {
|
|
1081
|
+
class LessonConversationService {
|
|
1115
1082
|
constructor() {
|
|
1116
1083
|
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
1117
1084
|
this.userService = inject(USER_DATA_EXCHANGE);
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* Builds the scenario prompt string based on lesson content and user info.
|
|
1121
|
-
* @param lessonText The extracted text content of the lesson.
|
|
1122
|
-
* @param userInformationPrompt The formatted string containing user details.
|
|
1123
|
-
* @returns The complete scenario prompt string.
|
|
1124
|
-
*/
|
|
1125
|
-
_buildScenarioPrompt(lessonText, userInformationPrompt) {
|
|
1126
|
-
return `
|
|
1127
|
-
${AppRolePlaySkill}
|
|
1128
|
-
<Lesson Text>
|
|
1129
|
-
${lessonText}
|
|
1130
|
-
${EngagementSkill}
|
|
1131
|
-
<User Information>
|
|
1132
|
-
${userInformationPrompt}`;
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Generates the necessary agent cards for a lesson chat session.
|
|
1136
|
-
* @param lesson The lesson data.
|
|
1137
|
-
* @returns An object containing the master agent card and the evaluator agent card.
|
|
1138
|
-
*/
|
|
1139
|
-
async generateAgentCards(lesson) {
|
|
1140
|
-
const lessonText = this.lessonsService.extractTextFromHtml(lesson.textCoded);
|
|
1141
|
-
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
1142
|
-
const scenario = this._buildScenarioPrompt(lessonText, userInformationPrompt);
|
|
1143
|
-
// Create a deep copy of the default card to avoid modifying the constant
|
|
1144
|
-
const masterAgent = JSON.parse(JSON.stringify(DEFAULT_LESSON_AGENT_CARD));
|
|
1145
|
-
masterAgent.characterCard.data.scenario = scenario;
|
|
1146
|
-
masterAgent.characterCard.data.post_history_instructions += `\n${userInformationPrompt}`;
|
|
1147
|
-
const evaluatorAgent = getDefaultLessonEvaluatorAgentCard(lessonText);
|
|
1148
|
-
return { masterAgent, evaluatorAgent };
|
|
1149
|
-
}
|
|
1150
|
-
/**
|
|
1151
|
-
* Generates conversation settings for a lesson, using the lesson scenario as the initial prompt.
|
|
1152
|
-
* @param lesson The lesson data.
|
|
1153
|
-
* @returns An IConversationSettings object configured for the lesson scenario.
|
|
1154
|
-
*/
|
|
1155
|
-
async generateConversationSettingsForLesson(lesson, settings) {
|
|
1156
|
-
// TODO: Consolidate user fetching logic if possible, or ensure consistency
|
|
1157
|
-
const baseLang = this.userService.getUserDataExchange()?.baseLang || 'en';
|
|
1158
|
-
let lessonText = '';
|
|
1159
|
-
if (lesson.textCoded) {
|
|
1160
|
-
lessonText = this.lessonsService.extractTextFromHtml(lesson.textCoded);
|
|
1161
|
-
}
|
|
1162
|
-
else {
|
|
1163
|
-
lessonText = lesson.markdown;
|
|
1164
|
-
}
|
|
1165
|
-
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
1166
|
-
let scenario = this._buildScenarioPrompt(lessonText, userInformationPrompt);
|
|
1167
|
-
if (settings.additionalPrompt) {
|
|
1168
|
-
scenario += '\n\n' + settings.additionalPrompt;
|
|
1169
|
-
}
|
|
1170
|
-
const initialMessage = {
|
|
1171
|
-
role: ChatRole.System,
|
|
1172
|
-
content: scenario,
|
|
1173
|
-
messageId: SystemPromptType.SystemPrompt,
|
|
1174
|
-
};
|
|
1175
|
-
// Use defaults similar to DEFAULT_LESSON_AGENT_CARD but adjust for prompt-based start
|
|
1176
|
-
const conversationSettings = {
|
|
1177
|
-
conversationType: ConversationType.General,
|
|
1178
|
-
textEngine: TextEngines.SimpleText,
|
|
1179
|
-
autoStart: true,
|
|
1180
|
-
messages: [initialMessage],
|
|
1181
|
-
model: { provider: 'google' },
|
|
1182
|
-
tts: { voice: getRandomQuickVoice(baseLang || 'en', 'female') },
|
|
1183
|
-
};
|
|
1184
|
-
return conversationSettings;
|
|
1185
|
-
}
|
|
1186
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1187
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, providedIn: 'root' }); }
|
|
1188
|
-
}
|
|
1189
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, decorators: [{
|
|
1190
|
-
type: Injectable,
|
|
1191
|
-
args: [{
|
|
1192
|
-
providedIn: 'root', // Or provide appropriately if it's library-specific
|
|
1193
|
-
}]
|
|
1194
|
-
}] });
|
|
1195
|
-
|
|
1196
|
-
class LessonConversationService {
|
|
1197
|
-
constructor() {
|
|
1198
|
-
this.lessonAIService = inject(LessonAIService);
|
|
1199
|
-
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
1200
1085
|
this.conversationSettings = signal(undefined, ...(ngDevMode ? [{ debugName: "conversationSettings" }] : []));
|
|
1201
1086
|
this.conversationFlow = signal(undefined, ...(ngDevMode ? [{ debugName: "conversationFlow" }] : []));
|
|
1202
1087
|
this.evalAgentTask = signal(undefined, ...(ngDevMode ? [{ debugName: "evalAgentTask" }] : []));
|
|
@@ -1205,7 +1090,7 @@ class LessonConversationService {
|
|
|
1205
1090
|
this.evalAgentTask.set({
|
|
1206
1091
|
systemPrompt: EnglishEvaluationSkill,
|
|
1207
1092
|
model: { provider: 'google' },
|
|
1208
|
-
task: `Please evaluate the user conversation student data is: \n ${this.
|
|
1093
|
+
task: `Please evaluate the user conversation student data is: \n ${this.userService.getUserDataInformation()}`,
|
|
1209
1094
|
expectedResponseType: EvalResultStringDefinition,
|
|
1210
1095
|
});
|
|
1211
1096
|
this.conversationFlow.set({
|
|
@@ -1260,7 +1145,7 @@ class LessonConversationService {
|
|
|
1260
1145
|
async startAI(lesson, settings) {
|
|
1261
1146
|
console.log('Requesting agent cards from LessonAIService...');
|
|
1262
1147
|
try {
|
|
1263
|
-
const conversationSettings = await this.
|
|
1148
|
+
const conversationSettings = await this.generateConversationSettingsForLesson(lesson, settings);
|
|
1264
1149
|
if (conversationSettings) {
|
|
1265
1150
|
this.conversationSettings.set(conversationSettings);
|
|
1266
1151
|
console.log('Agent cards received and set.');
|
|
@@ -1276,6 +1161,61 @@ class LessonConversationService {
|
|
|
1276
1161
|
return null;
|
|
1277
1162
|
}
|
|
1278
1163
|
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Builds the scenario prompt string based on lesson content and user info.
|
|
1166
|
+
* @param lessonText The extracted text content of the lesson.
|
|
1167
|
+
* @param userInformationPrompt The formatted string containing user details.
|
|
1168
|
+
* @returns The complete scenario prompt string.
|
|
1169
|
+
*/
|
|
1170
|
+
_buildLessonInstructionsPrompt(lessonText, userInformationPrompt, settings) {
|
|
1171
|
+
return `
|
|
1172
|
+
${settings.instructionsPrompt}
|
|
1173
|
+
|
|
1174
|
+
<Lesson Text>
|
|
1175
|
+
${lessonText}
|
|
1176
|
+
</Lesson Text>
|
|
1177
|
+
|
|
1178
|
+
${EngagementSkill}
|
|
1179
|
+
|
|
1180
|
+
<User Information>
|
|
1181
|
+
${userInformationPrompt}`;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Generates conversation settings for a lesson, using the lesson scenario as the initial prompt.
|
|
1185
|
+
* @param lesson The lesson data.
|
|
1186
|
+
* @returns An IConversationSettings object configured for the lesson scenario.
|
|
1187
|
+
*/
|
|
1188
|
+
async generateConversationSettingsForLesson(lesson, settings) {
|
|
1189
|
+
// TODO: Consolidate user fetching logic if possible, or ensure consistency
|
|
1190
|
+
const baseLang = this.userService.getUserDataExchange()?.baseLang || 'en';
|
|
1191
|
+
let lessonText = '';
|
|
1192
|
+
if (lesson.textCoded) {
|
|
1193
|
+
lessonText = this.lessonsService.extractTextFromHtml(lesson.textCoded);
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
lessonText = lesson.markdown;
|
|
1197
|
+
}
|
|
1198
|
+
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
1199
|
+
let lessonInstructionsPrompt = this._buildLessonInstructionsPrompt(lessonText, userInformationPrompt, settings);
|
|
1200
|
+
if (settings.additionalPrompt) {
|
|
1201
|
+
lessonInstructionsPrompt += '\n\n' + settings.additionalPrompt;
|
|
1202
|
+
}
|
|
1203
|
+
const initialMessage = {
|
|
1204
|
+
role: ChatRole.System,
|
|
1205
|
+
content: lessonInstructionsPrompt,
|
|
1206
|
+
messageId: SystemPromptType.SystemPrompt,
|
|
1207
|
+
};
|
|
1208
|
+
// Use defaults similar to DEFAULT_LESSON_AGENT_CARD but adjust for prompt-based start
|
|
1209
|
+
const conversationSettings = {
|
|
1210
|
+
conversationType: ConversationType.General,
|
|
1211
|
+
textEngine: TextEngines.SimpleText,
|
|
1212
|
+
autoStart: true,
|
|
1213
|
+
messages: [initialMessage],
|
|
1214
|
+
model: { provider: 'google' },
|
|
1215
|
+
tts: { voice: getRandomQuickVoice(baseLang || 'en', 'female') },
|
|
1216
|
+
};
|
|
1217
|
+
return conversationSettings;
|
|
1218
|
+
}
|
|
1279
1219
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonConversationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1280
1220
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonConversationService, providedIn: 'root' }); }
|
|
1281
1221
|
}
|
|
@@ -2112,10 +2052,8 @@ class DCLessonMetadataEditorComponent {
|
|
|
2112
2052
|
}
|
|
2113
2053
|
}
|
|
2114
2054
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonMetadataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2115
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2116
|
-
InputGroupModule }, { kind: "component", type: i5.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i6.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }
|
|
2117
|
-
FlagLanguagePipe, name: "flagEmoji" }, { kind: "pipe", type: // Added Pipe
|
|
2118
|
-
LangDescTranslation, name: "langDesc" }] }); }
|
|
2055
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: DCLessonMetadataEditorComponent, isStandalone: true, selector: "dc-lesson-metadata-editor", inputs: { form: "form", lesson: "lesson", isLoadingLesson: "isLoadingLesson" }, outputs: { saveRequest: "saveRequest", importNotionRequest: "importNotionRequest", improveNotionRequest: "improveNotionRequest" }, ngImport: i0, template: "<div>\n <!-- <div style=\"display: flex; gap: 10px; padding: 10px\">\n <p-button label=\"Guardar\" severity=\"primary\" (click)=\"emitSaveRequest()\" />\n <p-button label=\"Importar de Notion\" severity=\"help\" (click)=\"emitImportNotionRequest()\" />\n <p-button label=\"Mejorar Notion con AI\" severity=\"help\" (click)=\"emitImproveNotionRequest()\" />\n </div> -->\n\n <div>\n <div>\n <span>Nombre de La lecci\u00F3n</span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['name']\" type=\"text\" placeholder=\"Agrega un nombre\" />\n </div>\n <!-- <div>\n <span>T\u00EDtulo </span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['title']\" type=\"text\" placeholder=\"Agrega un t\u00EDtulo\" />\n </div> -->\n\n <div style=\"margin-top: 4px\">\n <span>Descripci\u00F3n </span>\n <p-inputgroup>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['description']\" type=\"text\" placeholder=\"Agrega una descripci\u00F3n\" />\n <p-button\n icon=\"pi pi-sparkles\"\n styleClass=\"p-button-secondary p-button-outlined\"\n pTooltip=\"Generar descripci\u00F3n con IA\"\n tooltipPosition=\"top\"\n [disabled]=\"isLoadingLesson\"\n (click)=\"triggerGenerateDescriptionAI()\" />\n </p-inputgroup>\n </div>\n </div>\n\n <div style=\"display: flex; align-items: center; margin-top: 10px\">\n <input\n pInputText\n style=\"flex: auto; margin-right: 5px\"\n [value]=\"lesson?.auditable?.prompt || ''\"\n (input)=\"handlePromptInputChange($event)\"\n type=\"text\"\n placeholder=\"Prompt para IA (opcional)\" />\n <p-button severity=\"primary\" label=\"Generar con IA\" icon=\"pi pi-sparkles\" [disabled]=\"isLoadingLesson\" (click)=\"generateByAI()\" />\n </div>\n\n <p-divider />\n\n <!-- <div style=\"display: flex; align-items: center; margin-top: 10px; gap: 10px\">\n <input pInputText [value]=\"lesson?.extensions?.['level'] || ''\" type=\"number\" placeholder=\"Nivel\" style=\"width: 80px\" />\n\n @if (lesson?.extensions) {\n <div>\n {{ lesson?.extensions?.['baseLang'] | flagEmoji }} -> {{ lesson?.extensions?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ lesson?.extensions?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ lesson?.extensions?.['targetLang'] | langDesc : 'es' }}\n </div>\n }\n </div> -->\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: // Added Pipe
|
|
2056
|
+
InputGroupModule }, { kind: "component", type: i5.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i6.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }] }); }
|
|
2119
2057
|
}
|
|
2120
2058
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonMetadataEditorComponent, decorators: [{
|
|
2121
2059
|
type: Component,
|
|
@@ -2130,7 +2068,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
2130
2068
|
LangDescTranslation, // Added Pipe
|
|
2131
2069
|
InputGroupModule,
|
|
2132
2070
|
DividerModule,
|
|
2133
|
-
], template: "<div>\n <!-- <div style=\"display: flex; gap: 10px; padding: 10px\">\n <p-button label=\"Guardar\" severity=\"primary\" (click)=\"emitSaveRequest()\" />\n <p-button label=\"Importar de Notion\" severity=\"help\" (click)=\"emitImportNotionRequest()\" />\n <p-button label=\"Mejorar Notion con AI\" severity=\"help\" (click)=\"emitImproveNotionRequest()\" />\n </div> -->\n\n <div>\n <div>\n <span>Nombre de La lecci\u00F3n</span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['name']\" type=\"text\" placeholder=\"Agrega un nombre\" />\n </div>\n <div>\n <span>T\u00EDtulo </span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['title']\" type=\"text\" placeholder=\"Agrega un t\u00EDtulo\" />\n </div
|
|
2071
|
+
], template: "<div>\n <!-- <div style=\"display: flex; gap: 10px; padding: 10px\">\n <p-button label=\"Guardar\" severity=\"primary\" (click)=\"emitSaveRequest()\" />\n <p-button label=\"Importar de Notion\" severity=\"help\" (click)=\"emitImportNotionRequest()\" />\n <p-button label=\"Mejorar Notion con AI\" severity=\"help\" (click)=\"emitImproveNotionRequest()\" />\n </div> -->\n\n <div>\n <div>\n <span>Nombre de La lecci\u00F3n</span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['name']\" type=\"text\" placeholder=\"Agrega un nombre\" />\n </div>\n <!-- <div>\n <span>T\u00EDtulo </span>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['title']\" type=\"text\" placeholder=\"Agrega un t\u00EDtulo\" />\n </div> -->\n\n <div style=\"margin-top: 4px\">\n <span>Descripci\u00F3n </span>\n <p-inputgroup>\n <input pInputText style=\"width: 100%\" [formControl]=\"form.controls['description']\" type=\"text\" placeholder=\"Agrega una descripci\u00F3n\" />\n <p-button\n icon=\"pi pi-sparkles\"\n styleClass=\"p-button-secondary p-button-outlined\"\n pTooltip=\"Generar descripci\u00F3n con IA\"\n tooltipPosition=\"top\"\n [disabled]=\"isLoadingLesson\"\n (click)=\"triggerGenerateDescriptionAI()\" />\n </p-inputgroup>\n </div>\n </div>\n\n <div style=\"display: flex; align-items: center; margin-top: 10px\">\n <input\n pInputText\n style=\"flex: auto; margin-right: 5px\"\n [value]=\"lesson?.auditable?.prompt || ''\"\n (input)=\"handlePromptInputChange($event)\"\n type=\"text\"\n placeholder=\"Prompt para IA (opcional)\" />\n <p-button severity=\"primary\" label=\"Generar con IA\" icon=\"pi pi-sparkles\" [disabled]=\"isLoadingLesson\" (click)=\"generateByAI()\" />\n </div>\n\n <p-divider />\n\n <!-- <div style=\"display: flex; align-items: center; margin-top: 10px; gap: 10px\">\n <input pInputText [value]=\"lesson?.extensions?.['level'] || ''\" type=\"number\" placeholder=\"Nivel\" style=\"width: 80px\" />\n\n @if (lesson?.extensions) {\n <div>\n {{ lesson?.extensions?.['baseLang'] | flagEmoji }} -> {{ lesson?.extensions?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ lesson?.extensions?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ lesson?.extensions?.['targetLang'] | langDesc : 'es' }}\n </div>\n }\n </div> -->\n</div>\n" }]
|
|
2134
2072
|
}], propDecorators: { form: [{
|
|
2135
2073
|
type: Input,
|
|
2136
2074
|
args: [{ required: true }]
|
|
@@ -2162,7 +2100,6 @@ class LessonFormEditorService {
|
|
|
2162
2100
|
version: ['1.0'],
|
|
2163
2101
|
id: [''],
|
|
2164
2102
|
name: [''],
|
|
2165
|
-
title: [''],
|
|
2166
2103
|
description: [''],
|
|
2167
2104
|
format: ['html'],
|
|
2168
2105
|
lang: [''],
|
|
@@ -2374,8 +2311,8 @@ class DCLessonEditorComponent extends EntityBaseFormComponent {
|
|
|
2374
2311
|
this.entityCommunicationService.partialUpdate(this.entityId(), { assets: event.assets });
|
|
2375
2312
|
}
|
|
2376
2313
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonEditorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2377
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DCLessonEditorComponent, isStandalone: true, selector: "dc-lesson-editor", providers: [LessonNotionService], usesInheritance: true, ngImport: i0, template: "<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader\n [assets]=\"entity()?.assets\"\n storagePath=\"lessons/{{ entityId() }}\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onAssetUpdate($event)\"></assets-loader>\n </div>\n\n
|
|
2378
|
-
DialogModule }, { kind: "component", type:
|
|
2314
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DCLessonEditorComponent, isStandalone: true, selector: "dc-lesson-editor", providers: [LessonNotionService], usesInheritance: true, ngImport: i0, template: "<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader\n [assets]=\"entity()?.assets\"\n storagePath=\"lessons/{{ entityId() }}\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onAssetUpdate($event)\"></assets-loader>\n </div>\n\n <!-- <div class=\"p-col-4\">\n <h3>Auditable</h3>\n <dc-auditable-viewer [data]=\"entity()?.auditable\"></dc-auditable-viewer>\n </div> -->\n <div class=\"p-col-4\">\n <h3>Gesti\u00F3n</h3>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </div>\n <div class=\"p-col-4\">\n <h3>Categorias y Etiquetas</h3>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </div>\n <!-- <div class=\"p-col-4\">\n <h3>Reactions</h3>\n <dc-reactions-viewer [data]=\"entity()?.reactions\"></dc-reactions-viewer>\n </div> -->\n\n <!-- <div class=\"p-col-4\">\n <h3>Extensions</h3>\n <dc-extensions-viewer [data]=\"entity()?.extensions\"></dc-extensions-viewer>\n </div> -->\n</div>\n\n<!-- Lesson Metadata Editor -->\n<br />\n<div [formGroup]=\"form\">\n <p-selectButton [options]=\"formatOptions\" formControlName=\"format\" optionLabel=\"label\" optionValue=\"value\" />\n</div>\n<dc-lesson-metadata-editor [lesson]=\"entity()\" [form]=\"form\" [isLoadingLesson]=\"isLoadingLesson()\"></dc-lesson-metadata-editor>\n\n<div style=\"margin-top: 30px\"></div>\n\n<!-- Component Adder -->\n<dc-lesson-component-adder (componentAdded)=\"onComponentAdded($event)\"></dc-lesson-component-adder>\n\n<!-- Display Added Components -->\n<div class=\"added-components-list\" style=\"margin-top: 15px; margin-bottom: 15px\">\n <h4>Componentes Agregados:</h4>\n @if (dynamicComponentsArray().length > 0) {\n <ul>\n @for (comp of dynamicComponentsArray(); track comp.id) {\n <li\n >ID: {{ comp.id }} - Tipo: {{ comp.component }}\n\n <button pButton icon=\"pi pi-info\" (click)=\"showComponentDetails(comp)\"></button>\n <p-button icon=\"pi pi-pencil\" [rounded]=\"true\" severity=\"warn\" (click)=\"editComponent(comp)\"></p-button>\n </li>\n }\n </ul>\n } @else {\n <p>A\u00FAn no se han agregado componentes.</p>\n }\n</div>\n\n<hr />\n\n<!-- Text Editor and Renderer -->\n<p-splitter [style]=\"{ height: '80vh' }\">\n <ng-template pTemplate>\n <ckeditor\n (keydown.control.s)=\"saveLesson($event)\"\n class=\"text-editor\"\n [editor]=\"editor\"\n [ngModel]=\"htmlTemporal\"\n (ngModelChange)=\"updateHtmlTextCoded('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"entity()\"></dc-lesson-renderer>\n </ng-template>\n</p-splitter>\n\n<div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"save()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n</div>\n\n<hr />\n\n<!-- <p-dialog header=\"Prompts\" [modal]=\"true\" [(visible)]=\"promptsVisible\" [style]=\"{ width: '70%' }\">\n <div>\n <h1>Banner</h1>\n <p>{{ prompts?.banner }}</p>\n <h1>Contenido</h1>\n <p>{{ prompts?.content }}</p>\n <h1>Descripci\u00F3n</h1>\n <p>{{ prompts?.description }}</p>\n </div>\n</p-dialog> -->\n", styles: [".btn{padding:.5rem 1rem;border-radius:4px;border:1px solid transparent;cursor:pointer}.generate-banner-btn{position:absolute;right:10px;top:10px}.prompt-visual{position:absolute;left:10px;bottom:10px}.btn-primary{background-color:#007bff;color:#fff}.btn-outline-primary{border-color:#007bff;color:#007bff}.btn-secondary{background-color:#6c757d;color:#fff}.btn-outline-secondary{border-color:#6c757d;color:#6c757d}.btn-rounded{border-radius:50%}.form-control{padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.25rem}.splitter{display:flex;gap:1rem}.splitter-panel{flex:1}.checkbox-container{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer}.mr-2{margin-right:.5rem}.header-cover{width:100%;height:250px;object-fit:cover;position:relative;border-radius:8px}.float-button{position:fixed;bottom:3.5rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}.text-editor{width:-webkit-fill-available;overflow-y:auto}:host ::ng-deep .p-inputtext{background:#fff3}::ng-deep .p-splitter .p-splitterpanel{overflow:auto!important}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: CKEditorModule }, { kind: "component", type: i3$1.CKEditorComponent, selector: "ckeditor", inputs: ["editor", "config", "data", "tagName", "watchdog", "editorWatchdogConfig", "disableTwoWayDataBinding", "disabled"], outputs: ["ready", "change", "blur", "focus", "error"] }, { kind: "component", type: DCLessonRendererComponent, selector: "dc-lesson-renderer", inputs: ["lessonInput", "lessonIdInput", "settings"], outputs: ["wordClicked"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i5$1.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: SplitterModule }, { kind: "component", type: i6$1.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i7.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "component", type: DCLessonComponentAdderComponent, selector: "dc-lesson-component-adder", outputs: ["componentAdded"] }, { kind: "ngmodule", type: // Add the component adder here
|
|
2315
|
+
DialogModule }, { kind: "component", type: AssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }, { kind: "component", type: DCLessonMetadataEditorComponent, selector: "dc-lesson-metadata-editor", inputs: ["form", "lesson", "isLoadingLesson"], outputs: ["saveRequest", "importNotionRequest", "improveNotionRequest"] }, { kind: "component", type: DcManageableFormComponent, selector: "dc-manageable-form", inputs: ["form"] }, { kind: "component", type: DcLearnableFormComponent, selector: "dc-learnable-form", inputs: ["form"] }] }); }
|
|
2379
2316
|
}
|
|
2380
2317
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonEditorComponent, decorators: [{
|
|
2381
2318
|
type: Component,
|
|
@@ -2391,15 +2328,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
2391
2328
|
TooltipModule,
|
|
2392
2329
|
DCLessonComponentAdderComponent, // Add the component adder here
|
|
2393
2330
|
DialogModule,
|
|
2394
|
-
DcExtensionsViewerComponent,
|
|
2395
|
-
DcLearnableViewerComponent,
|
|
2396
|
-
DcAuditableViewerComponent,
|
|
2397
|
-
DcReactionsViewerComponent,
|
|
2398
2331
|
AssetsLoaderComponent,
|
|
2399
2332
|
DCLessonMetadataEditorComponent,
|
|
2400
2333
|
DcManageableFormComponent,
|
|
2401
2334
|
DcLearnableFormComponent,
|
|
2402
|
-
], providers: [LessonNotionService], template: "<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader\n [assets]=\"entity()?.assets\"\n storagePath=\"lessons/{{ entityId() }}\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onAssetUpdate($event)\"></assets-loader>\n </div>\n\n
|
|
2335
|
+
], providers: [LessonNotionService], template: "<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader\n [assets]=\"entity()?.assets\"\n storagePath=\"lessons/{{ entityId() }}\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onAssetUpdate($event)\"></assets-loader>\n </div>\n\n <!-- <div class=\"p-col-4\">\n <h3>Auditable</h3>\n <dc-auditable-viewer [data]=\"entity()?.auditable\"></dc-auditable-viewer>\n </div> -->\n <div class=\"p-col-4\">\n <h3>Gesti\u00F3n</h3>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </div>\n <div class=\"p-col-4\">\n <h3>Categorias y Etiquetas</h3>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </div>\n <!-- <div class=\"p-col-4\">\n <h3>Reactions</h3>\n <dc-reactions-viewer [data]=\"entity()?.reactions\"></dc-reactions-viewer>\n </div> -->\n\n <!-- <div class=\"p-col-4\">\n <h3>Extensions</h3>\n <dc-extensions-viewer [data]=\"entity()?.extensions\"></dc-extensions-viewer>\n </div> -->\n</div>\n\n<!-- Lesson Metadata Editor -->\n<br />\n<div [formGroup]=\"form\">\n <p-selectButton [options]=\"formatOptions\" formControlName=\"format\" optionLabel=\"label\" optionValue=\"value\" />\n</div>\n<dc-lesson-metadata-editor [lesson]=\"entity()\" [form]=\"form\" [isLoadingLesson]=\"isLoadingLesson()\"></dc-lesson-metadata-editor>\n\n<div style=\"margin-top: 30px\"></div>\n\n<!-- Component Adder -->\n<dc-lesson-component-adder (componentAdded)=\"onComponentAdded($event)\"></dc-lesson-component-adder>\n\n<!-- Display Added Components -->\n<div class=\"added-components-list\" style=\"margin-top: 15px; margin-bottom: 15px\">\n <h4>Componentes Agregados:</h4>\n @if (dynamicComponentsArray().length > 0) {\n <ul>\n @for (comp of dynamicComponentsArray(); track comp.id) {\n <li\n >ID: {{ comp.id }} - Tipo: {{ comp.component }}\n\n <button pButton icon=\"pi pi-info\" (click)=\"showComponentDetails(comp)\"></button>\n <p-button icon=\"pi pi-pencil\" [rounded]=\"true\" severity=\"warn\" (click)=\"editComponent(comp)\"></p-button>\n </li>\n }\n </ul>\n } @else {\n <p>A\u00FAn no se han agregado componentes.</p>\n }\n</div>\n\n<hr />\n\n<!-- Text Editor and Renderer -->\n<p-splitter [style]=\"{ height: '80vh' }\">\n <ng-template pTemplate>\n <ckeditor\n (keydown.control.s)=\"saveLesson($event)\"\n class=\"text-editor\"\n [editor]=\"editor\"\n [ngModel]=\"htmlTemporal\"\n (ngModelChange)=\"updateHtmlTextCoded('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"entity()\"></dc-lesson-renderer>\n </ng-template>\n</p-splitter>\n\n<div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"save()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n</div>\n\n<hr />\n\n<!-- <p-dialog header=\"Prompts\" [modal]=\"true\" [(visible)]=\"promptsVisible\" [style]=\"{ width: '70%' }\">\n <div>\n <h1>Banner</h1>\n <p>{{ prompts?.banner }}</p>\n <h1>Contenido</h1>\n <p>{{ prompts?.content }}</p>\n <h1>Descripci\u00F3n</h1>\n <p>{{ prompts?.description }}</p>\n </div>\n</p-dialog> -->\n", styles: [".btn{padding:.5rem 1rem;border-radius:4px;border:1px solid transparent;cursor:pointer}.generate-banner-btn{position:absolute;right:10px;top:10px}.prompt-visual{position:absolute;left:10px;bottom:10px}.btn-primary{background-color:#007bff;color:#fff}.btn-outline-primary{border-color:#007bff;color:#007bff}.btn-secondary{background-color:#6c757d;color:#fff}.btn-outline-secondary{border-color:#6c757d;color:#6c757d}.btn-rounded{border-radius:50%}.form-control{padding:.375rem .75rem;border:1px solid #ced4da;border-radius:.25rem}.splitter{display:flex;gap:1rem}.splitter-panel{flex:1}.checkbox-container{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer}.mr-2{margin-right:.5rem}.header-cover{width:100%;height:250px;object-fit:cover;position:relative;border-radius:8px}.float-button{position:fixed;bottom:3.5rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}.text-editor{width:-webkit-fill-available;overflow-y:auto}:host ::ng-deep .p-inputtext{background:#fff3}::ng-deep .p-splitter .p-splitterpanel{overflow:auto!important}\n"] }]
|
|
2403
2336
|
}] });
|
|
2404
2337
|
|
|
2405
2338
|
class LessonsV2Component {
|