@dataclouder/ngx-lessons 0.1.2 → 0.1.3
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 +771 -452
- package/fesm2022/dataclouder-ngx-lessons.mjs.map +1 -1
- package/lib/components/courses/course-detail/course-detail.component.d.ts +5 -0
- package/lib/components/courses/course-form/course-form.component.d.ts +35 -0
- package/lib/components/courses/course-list/course-list.component.d.ts +25 -0
- package/lib/components/courses/courses.component.d.ts +5 -0
- package/lib/components/courses/courses.service.d.ts +14 -0
- package/lib/components/courses/models/courses.model.d.ts +24 -0
- package/lib/components/courses-admin/courses-admin.component.d.ts +8 -0
- package/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.d.ts +1 -1
- package/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.d.ts +2 -0
- package/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.d.ts +11 -5
- package/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.d.ts +5 -9
- package/lib/components/dynamic-components/dynamic-components-builder.service.d.ts +8 -0
- package/lib/components/dynamic-components/dynamic-components.service.d.ts +30 -0
- package/lib/components/{lesson-mini-components/components → dynamic-components}/selector/selector-builder/selector-builder.component.d.ts +4 -7
- package/lib/components/{lesson-mini-components/components → dynamic-components}/selector/selector.component.d.ts +2 -2
- package/lib/components/lesson-mini-components/components/ComponentBuilder.d.ts +8 -6
- package/lib/components/lesson-mini-components/components/lessons.clases.d.ts +8 -18
- package/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.d.ts +1 -0
- package/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.d.ts +2 -9
- package/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.d.ts +2 -8
- package/lib/models/lessons.pipes.d.ts +16 -0
- package/lib/services/courses.service.d.ts +7 -0
- package/lib/services/lesson-ai.service.d.ts +2 -1
- package/package.json +1 -1
- package/public-api.d.ts +10 -2
|
@@ -1,68 +1,245 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Pipe, InjectionToken, inject, Input, Component, ChangeDetectionStrategy, signal, EventEmitter, Output, ChangeDetectorRef, ViewChildren, Injectable, input, Renderer2, ViewContainerRef, computed, effect, ViewChild, output } from '@angular/core';
|
|
3
|
+
import * as i1$2 from 'primeng/paginator';
|
|
4
|
+
import { PaginatorModule } from 'primeng/paginator';
|
|
5
|
+
import { DatePipe, NgComponentOutlet, KeyValuePipe, CommonModule, SlicePipe } from '@angular/common';
|
|
6
|
+
import * as i1$3 from '@angular/router';
|
|
7
|
+
import { RouterModule, ActivatedRoute, Router } from '@angular/router';
|
|
8
|
+
import { PaginationBase, TOAST_ALERTS_TOKEN, DCFilterBarComponent, QuickTableComponent, LoadingBarService, HttpCoreService, PromptService } from '@dataclouder/ngx-core';
|
|
3
9
|
import * as i1 from '@angular/forms';
|
|
4
|
-
import { FormControl,
|
|
5
|
-
import * as i4 from 'primeng/inputtext';
|
|
6
|
-
import { InputTextModule } from 'primeng/inputtext';
|
|
10
|
+
import { FormBuilder, FormControl, FormArray, FormsModule, ReactiveFormsModule, UntypedFormControl, FormGroup, Validators } from '@angular/forms';
|
|
7
11
|
import * as i1$1 from 'primeng/button';
|
|
8
12
|
import { ButtonModule } from 'primeng/button';
|
|
9
|
-
import * as
|
|
10
|
-
import {
|
|
13
|
+
import * as i3 from 'primeng/inputtext';
|
|
14
|
+
import { InputTextModule } from 'primeng/inputtext';
|
|
15
|
+
import { DynamicDialogRef, DialogService } from 'primeng/dynamicdialog';
|
|
11
16
|
import { nanoid } from 'nanoid';
|
|
12
|
-
import * as i2 from 'primeng/dynamicdialog';
|
|
13
|
-
import { DialogService } from 'primeng/dynamicdialog';
|
|
14
|
-
import * as i2$1 from 'primeng/select';
|
|
15
|
-
import { SelectModule } from 'primeng/select';
|
|
16
17
|
import { DropdownModule } from 'primeng/dropdown';
|
|
17
|
-
import { NgxTtsComponent } from '@dataclouder/ngx-tts';
|
|
18
|
-
import * as
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import { RouterModule, ActivatedRoute, Router } from '@angular/router';
|
|
23
|
-
import * as i4$2 from '@dataclouder/ngx-core';
|
|
24
|
-
import { PaginationBase, TOAST_ALERTS_TOKEN, DCFilterBarComponent, QuickTableComponent, LoadingBarService, HttpCoreService, PromptService } from '@dataclouder/ngx-core';
|
|
18
|
+
import { NgxTtsComponent, getRandomQuickVoice } from '@dataclouder/ngx-tts';
|
|
19
|
+
import * as i4 from 'primeng/message';
|
|
20
|
+
import { MessageModule } from 'primeng/message';
|
|
21
|
+
import * as i2 from 'primeng/select';
|
|
22
|
+
import { SelectModule } from 'primeng/select';
|
|
25
23
|
import { PopoverModule } from 'primeng/popover';
|
|
26
24
|
import * as i4$1 from 'primeng/tag';
|
|
27
25
|
import { TagModule } from 'primeng/tag';
|
|
28
|
-
import * as i2$
|
|
26
|
+
import * as i2$1 from 'primeng/speeddial';
|
|
29
27
|
import { SpeedDialModule } from 'primeng/speeddial';
|
|
30
|
-
import * as i3 from 'primeng/card';
|
|
28
|
+
import * as i3$1 from 'primeng/card';
|
|
31
29
|
import { CardModule } from 'primeng/card';
|
|
32
30
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
33
31
|
import { map } from 'rxjs';
|
|
34
32
|
import BalloonEditor from '@ckeditor/ckeditor5-build-balloon-block';
|
|
35
|
-
import * as i3$
|
|
33
|
+
import * as i3$2 from '@ckeditor/ckeditor5-angular';
|
|
36
34
|
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
|
|
37
|
-
import * as i5$
|
|
35
|
+
import * as i5$1 from 'primeng/splitter';
|
|
38
36
|
import { SplitterModule } from 'primeng/splitter';
|
|
39
|
-
import * as
|
|
37
|
+
import * as i6 from 'primeng/tooltip';
|
|
40
38
|
import { TooltipModule } from 'primeng/tooltip';
|
|
41
39
|
import { ResolutionType, AspectType, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
|
|
42
|
-
import { TextEngines, ConversationType, USER_DATA_EXCHANGE, ChatRole, EvalResultStringDefinition, ChatEventType, DCChatComponent, CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
43
|
-
import * as i2$
|
|
40
|
+
import { TextEngines, ConversationType, USER_DATA_EXCHANGE, ChatRole, EvalResultStringDefinition, ConversationEvents, ChatEventType, DCChatComponent, CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
41
|
+
import * as i2$2 from 'primeng/drawer';
|
|
44
42
|
import { DrawerModule } from 'primeng/drawer';
|
|
45
43
|
import * as i7 from 'primeng/dialog';
|
|
46
44
|
import { DialogModule } from 'primeng/dialog';
|
|
47
45
|
import TurndownService from 'turndown';
|
|
48
46
|
import { marked } from 'marked';
|
|
49
|
-
import * as i5
|
|
47
|
+
import * as i5 from 'primeng/inputgroup';
|
|
50
48
|
import { InputGroupModule } from 'primeng/inputgroup';
|
|
51
|
-
import * as i6 from 'primeng/divider';
|
|
49
|
+
import * as i6$1 from 'primeng/divider';
|
|
52
50
|
import { DividerModule } from 'primeng/divider';
|
|
53
51
|
import { NgxVertexService, ChatRoleVertex } from '@dataclouder/ngx-vertex';
|
|
54
|
-
import * as i2$
|
|
52
|
+
import * as i2$3 from 'primeng/api';
|
|
53
|
+
import * as i3$3 from 'primeng/textarea';
|
|
54
|
+
import { TextareaModule } from 'primeng/textarea';
|
|
55
|
+
import { ChipModule } from 'primeng/chip';
|
|
56
|
+
import { FormlyModule } from '@ngx-formly/core';
|
|
57
|
+
import { TableModule } from 'primeng/table';
|
|
58
|
+
|
|
59
|
+
// import { LangCodeDescription, LangCodeDescriptionEs } from '../components/lesson-mini-components/components/lessons.clases';
|
|
60
|
+
// This pipe should not be here in the lessons, refactor when is posible and remove LangCodeDescription
|
|
61
|
+
const LangCodeDescription = {
|
|
62
|
+
es: 'Spanish',
|
|
63
|
+
en: 'English',
|
|
64
|
+
it: 'Italian',
|
|
65
|
+
pt: 'Portuguese',
|
|
66
|
+
fr: 'French',
|
|
67
|
+
ja: 'Japanese',
|
|
68
|
+
};
|
|
69
|
+
const LangCodeDescriptionEs = {
|
|
70
|
+
es: 'Español',
|
|
71
|
+
en: 'Inglés',
|
|
72
|
+
it: 'Italiano',
|
|
73
|
+
pt: 'Portugués',
|
|
74
|
+
fr: 'Frances',
|
|
75
|
+
ja: 'Japonés',
|
|
76
|
+
};
|
|
77
|
+
class LangDescTranslationPipe {
|
|
78
|
+
transform(value, lang) {
|
|
79
|
+
if (lang === 'es') {
|
|
80
|
+
return LangCodeDescriptionEs[value];
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return LangCodeDescription[value];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: LangDescTranslationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
87
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.4", ngImport: i0, type: LangDescTranslationPipe, isStandalone: true, name: "langDesc" }); }
|
|
88
|
+
}
|
|
89
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: LangDescTranslationPipe, decorators: [{
|
|
90
|
+
type: Pipe,
|
|
91
|
+
args: [{
|
|
92
|
+
name: 'langDesc',
|
|
93
|
+
standalone: true,
|
|
94
|
+
}]
|
|
95
|
+
}] });
|
|
96
|
+
class FlagLanguagePipe {
|
|
97
|
+
transform(lang) {
|
|
98
|
+
if (lang === 'en') {
|
|
99
|
+
return '🇺🇸';
|
|
100
|
+
}
|
|
101
|
+
else if (lang === 'es') {
|
|
102
|
+
return '🇲🇽';
|
|
103
|
+
}
|
|
104
|
+
else if (lang === 'fr') {
|
|
105
|
+
return '🇫🇷';
|
|
106
|
+
}
|
|
107
|
+
else if (lang === 'it') {
|
|
108
|
+
return '🇮🇹';
|
|
109
|
+
}
|
|
110
|
+
else if (lang === 'pt') {
|
|
111
|
+
return '🇧🇷';
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FlagLanguagePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
118
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.4", ngImport: i0, type: FlagLanguagePipe, isStandalone: true, name: "flagEmoji" }); }
|
|
119
|
+
}
|
|
120
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FlagLanguagePipe, decorators: [{
|
|
121
|
+
type: Pipe,
|
|
122
|
+
args: [{
|
|
123
|
+
name: 'flagEmoji',
|
|
124
|
+
standalone: true,
|
|
125
|
+
}]
|
|
126
|
+
}] });
|
|
127
|
+
|
|
128
|
+
// NOTE: what to do? IAgent Deponds on ngx-agent-cards but lessons don't
|
|
129
|
+
// import { IAgentCard } from '@dataclouder/ngx-agent-cards';
|
|
130
|
+
const NOTION_SERVICE_TOKEN = new InjectionToken('notion.service');
|
|
131
|
+
class NotionAbstractService {
|
|
132
|
+
}
|
|
133
|
+
function provideNotionService(serviceImplementation) {
|
|
134
|
+
return [
|
|
135
|
+
{
|
|
136
|
+
provide: NOTION_SERVICE_TOKEN,
|
|
137
|
+
useExisting: serviceImplementation,
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
var NotionExportType;
|
|
142
|
+
(function (NotionExportType) {
|
|
143
|
+
NotionExportType["HTML"] = "html";
|
|
144
|
+
NotionExportType["MARKDOWN"] = "markdown";
|
|
145
|
+
NotionExportType["PLAIN_TEXT"] = "plain_text";
|
|
146
|
+
NotionExportType["SIMPLE_BLOCKS"] = "simple_blocks";
|
|
147
|
+
})(NotionExportType || (NotionExportType = {}));
|
|
148
|
+
|
|
149
|
+
const MarkdownWriterSkill = `
|
|
150
|
+
You are an Expert Markdown Writer with the following qualities:
|
|
151
|
+
You are a world-class Markdown formatting specialist who excels at organizing information in a visually appealing and highly accessible manner. Your writing combines technical precision with creative presentation to engage readers of all backgrounds.
|
|
152
|
+
Your Core Skills 📝
|
|
153
|
+
|
|
154
|
+
You transform complex information into beautifully structured Markdown documents
|
|
155
|
+
You strategically use headings, lists, and formatting to create clear visual hierarchies
|
|
156
|
+
You incorporate helpful emojis to enhance readability and engagement
|
|
157
|
+
You write in a clear, concise style that's accessible to general audiences
|
|
158
|
+
|
|
159
|
+
Your Process Approach 🔄
|
|
160
|
+
|
|
161
|
+
You always begin with a logical document structure before adding content
|
|
162
|
+
You organize information into clearly defined sections with descriptive headings
|
|
163
|
+
You balance visual elements with textual content for optimal readability
|
|
164
|
+
You maintain consistent formatting patterns throughout documents
|
|
165
|
+
|
|
166
|
+
Your Writing Style ✨
|
|
167
|
+
|
|
168
|
+
You use simple, direct language that's easy for everyone to understand
|
|
169
|
+
You explain technical concepts using everyday examples and analogies
|
|
170
|
+
You create a friendly, conversational tone while maintaining professionalism
|
|
171
|
+
You break down complex ideas into manageable segments
|
|
172
|
+
|
|
173
|
+
Your Special Touches 🎯
|
|
174
|
+
|
|
175
|
+
You know exactly when and where to add emojis for maximum impact
|
|
176
|
+
You create custom tables to present comparative information effectively
|
|
177
|
+
You use blockquotes to highlight important takeaways
|
|
178
|
+
You incorporate visual dividers to separate major content sections
|
|
179
|
+
|
|
180
|
+
When responding to requests, you'll first understand the subject matter, then organize it into a logical structure with clear headings, appropriate formatting elements, and helpful visual enhancements. Your goal is always to create content that's not only informative but also visually engaging and accessible to all readers.
|
|
181
|
+
`;
|
|
182
|
+
const UserRequirements = `
|
|
183
|
+
User also can provide additional instructions or requirements for the lesson or current lesson to improve it.
|
|
184
|
+
`;
|
|
185
|
+
const LanguageLessonSkill = (langBase, langTarget) => `
|
|
186
|
+
|
|
187
|
+
You are also a ${langTarget} lesson professor, you write lessons for ${langBase} learners.
|
|
188
|
+
explain the best you can will all your experience teaching.
|
|
189
|
+
|
|
190
|
+
You can infer the level of the lesson from the content or user request, so can increase difficulty
|
|
191
|
+
|
|
192
|
+
For Basic Level: generate a ${langTarget} lesson for ${langBase} learners at a basic level (A1-A2).
|
|
193
|
+
|
|
194
|
+
Include:
|
|
195
|
+
|
|
196
|
+
- Simple dialogues or short texts.
|
|
197
|
+
- Key vocabulary with simple definitions or ${langBase} translations.
|
|
198
|
+
- Basic grammar points explained simply (e.g., "to be" verb, simple present).
|
|
199
|
+
- Practice exercises (e.g., fill-in-the-blanks, simple questions).
|
|
200
|
+
|
|
201
|
+
For Intermediate Level: generate a ${langTarget} lesson for ${langBase} learners at a medium level (B1-B2).
|
|
202
|
+
|
|
203
|
+
Include:
|
|
204
|
+
|
|
205
|
+
- Texts or dialogues of moderate length and complexity.
|
|
206
|
+
- New vocabulary and common phrasal verbs with context.
|
|
207
|
+
- Explanation and practice of intermediate grammar points (e.g., past simple vs. present perfect, conditionals).
|
|
208
|
+
- Exercises that require more detailed responses or understanding.
|
|
209
|
+
- The content should be engaging and cover topics relevant to daily life, work, or hobbies.
|
|
210
|
+
|
|
211
|
+
For Advanced Level: generate a ${langTarget} lesson for ${langBase} learners at an advanced level (C1-C2).
|
|
212
|
+
|
|
213
|
+
Include:
|
|
214
|
+
|
|
215
|
+
- Challenging texts or discussions.
|
|
216
|
+
- Advanced vocabulary, idioms, and nuanced expressions.
|
|
217
|
+
- Exploration of complex grammar or stylistic points.
|
|
218
|
+
- Exercises that encourage critical thinking, debate, or detailed writing.
|
|
219
|
+
- The content should be stimulating and cover a wide range of topics, including academic or professional contexts.
|
|
220
|
+
`;
|
|
221
|
+
const getLanguageSimpleAgent = (langBase, langTarget) => {
|
|
222
|
+
return {
|
|
223
|
+
systemPrompt: `
|
|
224
|
+
${MarkdownWriterSkill}
|
|
225
|
+
${LanguageLessonSkill(langBase, langTarget)}
|
|
226
|
+
${UserRequirements}
|
|
227
|
+
|
|
228
|
+
`,
|
|
229
|
+
model: { id: 'gemini-2.5-flash-preview-04-17', provider: 'google' },
|
|
230
|
+
};
|
|
231
|
+
};
|
|
55
232
|
|
|
56
233
|
class ComponentBuilder {
|
|
57
|
-
constructor(
|
|
58
|
-
this.formBuilder =
|
|
59
|
-
this.ref =
|
|
234
|
+
constructor() {
|
|
235
|
+
this.formBuilder = inject(FormBuilder);
|
|
236
|
+
this.ref = inject(DynamicDialogRef);
|
|
60
237
|
// Sobreescribir si es necesario
|
|
61
238
|
// public formGroup = this.formBuilder.group<LessonCompSettings>({});
|
|
62
239
|
this.formGroup = this.formBuilder.group({
|
|
63
240
|
response: new FormControl(null),
|
|
64
241
|
responses: new FormControl(null),
|
|
65
|
-
options:
|
|
242
|
+
options: new FormArray([]),
|
|
66
243
|
text: new FormControl(null),
|
|
67
244
|
hint: new FormControl(null),
|
|
68
245
|
explanation: new FormControl(null),
|
|
@@ -87,7 +264,7 @@ class ComponentBuilder {
|
|
|
87
264
|
delete data[key];
|
|
88
265
|
}
|
|
89
266
|
});
|
|
90
|
-
const code = { component: this.
|
|
267
|
+
const code = { component: this.componentName, inputs: { ...data } };
|
|
91
268
|
return code;
|
|
92
269
|
}
|
|
93
270
|
showCode() {
|
|
@@ -97,8 +274,13 @@ class ComponentBuilder {
|
|
|
97
274
|
}
|
|
98
275
|
getComponentData() {
|
|
99
276
|
const code = this.getCode();
|
|
100
|
-
|
|
101
|
-
|
|
277
|
+
if (this.id) {
|
|
278
|
+
code.id = this.id;
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
const id = nanoid().replace(/-/g, '_');
|
|
282
|
+
code.id = id;
|
|
283
|
+
}
|
|
102
284
|
return { str: `~${JSON.stringify(code)}~`, obj: code };
|
|
103
285
|
}
|
|
104
286
|
// TODO: for now copyToClipboard is the that that closes modal and return data.
|
|
@@ -107,8 +289,8 @@ class ComponentBuilder {
|
|
|
107
289
|
await navigator.clipboard.writeText(data.str);
|
|
108
290
|
this.ref.close(data);
|
|
109
291
|
}
|
|
110
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ComponentBuilder, deps: [
|
|
111
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ComponentBuilder, isStandalone: true, selector: "app-component-builder", ngImport: i0, template: '<div>no template</div>', isInline: true }); }
|
|
292
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ComponentBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
293
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: ComponentBuilder, isStandalone: true, selector: "app-component-builder", inputs: { inputs: "inputs", id: "id" }, ngImport: i0, template: '<div>no template</div>', isInline: true }); }
|
|
112
294
|
}
|
|
113
295
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ComponentBuilder, decorators: [{
|
|
114
296
|
type: Component,
|
|
@@ -116,7 +298,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
116
298
|
selector: 'app-component-builder',
|
|
117
299
|
template: '<div>no template</div>',
|
|
118
300
|
}]
|
|
119
|
-
}],
|
|
301
|
+
}], propDecorators: { inputs: [{
|
|
302
|
+
type: Input
|
|
303
|
+
}], id: [{
|
|
304
|
+
type: Input
|
|
305
|
+
}] } });
|
|
306
|
+
|
|
307
|
+
class TextWriterBuiderComponent extends ComponentBuilder {
|
|
308
|
+
constructor() {
|
|
309
|
+
super(...arguments);
|
|
310
|
+
this.componentName = 'TextWriter';
|
|
311
|
+
}
|
|
312
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterBuiderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
313
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TextWriterBuiderComponent, isStandalone: true, selector: "app-text-writer-buider", usesInheritance: true, ngImport: i0, template: "<div>\r\n <div>\r\n <h5>Constructor de formulario con texto</h5>\r\n </div>\r\n\r\n <div>\r\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\r\n <input pInputText type=\"text\" nbInput fullWidth formControlName=\"response\" placeholder=\"Respuesta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"\" nbInput fullWidth formControlName=\"hint\"\r\n placeholder=\"Escribe una pista para esta pregunta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"text\" nbInput fullWidth formControlName=\"explanation\"\r\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\r\n </form>\r\n </div>\r\n\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\"\r\n [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\"\r\n severity=\"secondary\"></p-button>\r\n </div>\r\n</div>", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }] }); }
|
|
314
|
+
}
|
|
315
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterBuiderComponent, decorators: [{
|
|
316
|
+
type: Component,
|
|
317
|
+
args: [{ selector: 'app-text-writer-buider', standalone: true, imports: [FormsModule, ReactiveFormsModule, ButtonModule, InputTextModule], template: "<div>\r\n <div>\r\n <h5>Constructor de formulario con texto</h5>\r\n </div>\r\n\r\n <div>\r\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\r\n <input pInputText type=\"text\" nbInput fullWidth formControlName=\"response\" placeholder=\"Respuesta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"\" nbInput fullWidth formControlName=\"hint\"\r\n placeholder=\"Escribe una pista para esta pregunta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"text\" nbInput fullWidth formControlName=\"explanation\"\r\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\r\n </form>\r\n </div>\r\n\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\"\r\n [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\"\r\n severity=\"secondary\"></p-button>\r\n </div>\r\n</div>", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"] }]
|
|
318
|
+
}] });
|
|
120
319
|
|
|
121
320
|
class ComponentWithForm {
|
|
122
321
|
constructor() {
|
|
@@ -142,111 +341,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
142
341
|
}]
|
|
143
342
|
}] });
|
|
144
343
|
|
|
145
|
-
class SelectorComponent extends ComponentWithForm {
|
|
146
|
-
constructor() {
|
|
147
|
-
super();
|
|
148
|
-
this.isFilled = false;
|
|
149
|
-
}
|
|
150
|
-
evaluate() {
|
|
151
|
-
let result;
|
|
152
|
-
if (this.control.value == null) {
|
|
153
|
-
result = null;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
result = this.control.value?.toLowerCase().trim() === this.config.settings.response.toLowerCase().trim();
|
|
157
|
-
}
|
|
158
|
-
if (result) {
|
|
159
|
-
this.status = 'success';
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
this.status = 'danger';
|
|
163
|
-
}
|
|
164
|
-
this.isFilled = true;
|
|
165
|
-
return result;
|
|
166
|
-
}
|
|
167
|
-
validate() {
|
|
168
|
-
if (this.control.invalid) {
|
|
169
|
-
this.status = 'warning';
|
|
170
|
-
}
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
174
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: SelectorComponent, isStandalone: true, selector: "app-selector", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: "<p-select [class]=\"status\" placeholder=\"Selecciona\" [options]=\"config.settings.options\" [formControl]=\"control\"></p-select>\r\n", styles: ["::ng-deep .comp-selector button{min-width:80px}.warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i2$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
|
|
175
|
-
}
|
|
176
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorComponent, decorators: [{
|
|
177
|
-
type: Component,
|
|
178
|
-
args: [{ selector: 'app-selector', standalone: true, imports: [FormsModule, ReactiveFormsModule, SelectModule], template: "<p-select [class]=\"status\" placeholder=\"Selecciona\" [options]=\"config.settings.options\" [formControl]=\"control\"></p-select>\r\n", styles: ["::ng-deep .comp-selector button{min-width:80px}.warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"] }]
|
|
179
|
-
}], ctorParameters: () => [], propDecorators: { config: [{
|
|
180
|
-
type: Input
|
|
181
|
-
}] } });
|
|
182
|
-
|
|
183
|
-
class SelectorBuilderComponent extends ComponentBuilder {
|
|
184
|
-
constructor(formBuilder,
|
|
185
|
-
// protected override toastrService: ToastService,
|
|
186
|
-
ref) {
|
|
187
|
-
super(formBuilder, null);
|
|
188
|
-
this.formBuilder = formBuilder;
|
|
189
|
-
this.ref = ref;
|
|
190
|
-
this.sampleConfig = {
|
|
191
|
-
id: '1',
|
|
192
|
-
component: LessonComponentEnum.Selector,
|
|
193
|
-
settings: {
|
|
194
|
-
options: ['fourteen ninety-two', 'fourteen ninety-six', 'fifteen ninety-one'],
|
|
195
|
-
response: 'fourteen ninety-two',
|
|
196
|
-
hint: 'Pista para la respuesta',
|
|
197
|
-
explanation: 'Explicación de la respuesta',
|
|
198
|
-
responses: 'Opción 1, Opción 2, Opción 3',
|
|
199
|
-
text: 'Texto de la pregunta',
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
// public formGroup = this.formBuilder.group({
|
|
204
|
-
// options: this.formBuilder.array([]),
|
|
205
|
-
// response: ['', Validators.required],
|
|
206
|
-
// hint: [],
|
|
207
|
-
// explanation: [],
|
|
208
|
-
// });
|
|
209
|
-
ngOnInit() {
|
|
210
|
-
this.formGroup.get('response');
|
|
211
|
-
}
|
|
212
|
-
//TODO Probablemente estos 3 pueden irse a una clase abstracta
|
|
213
|
-
pushControlToFormArray(controlName) {
|
|
214
|
-
this.formGroup.controls.options.push(this.formBuilder.control(''));
|
|
215
|
-
// (this.formGroup.get(controlName) as UntypedFormArray).push(this.formBuilder.control(''));
|
|
216
|
-
console.log(this.formGroup.controls.options);
|
|
217
|
-
}
|
|
218
|
-
deleteFormArrayByIndex(controlName, index) {
|
|
219
|
-
this.formGroup.get(controlName).removeAt(index);
|
|
220
|
-
}
|
|
221
|
-
get optionsForm() {
|
|
222
|
-
return this.formGroup.get('options');
|
|
223
|
-
}
|
|
224
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorBuilderComponent, deps: [{ token: i1.FormBuilder }, { token: i2.DynamicDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
225
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: SelectorBuilderComponent, isStandalone: true, selector: "app-selector-builder", usesInheritance: true, ngImport: i0, template: "<div>\n <div>\n <p-message>Construcci\u00F3n del componente de Selecci\u00F3n, sirve para hacer una pregunta y mostrar varias opciones, ejemplo:</p-message>\n </div>\n\n <div>\n <span>En que a\u00F1o lleg\u00F3 cristobal colon a america?</span>\n <app-selector [config]=\"sampleConfig\"></app-selector>\n </div>\n\n <hr />\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input class=\"form-input\" type=\"text\" pInputText fullWidth formControlName=\"response\" placeholder=\"Respuesta Correcta...\" />\n <br />\n\n <input class=\"form-input\" type=\"\" pInputText fullWidth formControlName=\"hint\" placeholder=\"Escribe una pista para esta pregunta\" />\n\n <br />\n <input\n class=\"form-input\"\n type=\"text\"\n pInputText\n fullWidth\n formControlName=\"explanation\"\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\n\n <hr />\n <h6>Opciones</h6>\n\n <div class=\"form-group\" formArrayName=\"options\">\n @for (item of optionsForm.controls; track item; let i = $index) {\n <div\n style=\"display: flex; gap: 10px; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-direction: column\"\n >\n <div>\n <input type=\"text\" pInputText fullWidth [formControlName]=\"i\" />\n <p-button (click)=\"deleteFormArrayByIndex('options', i)\" icon=\"pi pi-times\" severity=\"danger\"></p-button>\n </div>\n </div>\n }\n </div>\n\n <p-button (click)=\"pushControlToFormArray('options')\" label=\"Agregar Opci\u00F3n\" [text]=\"true\" severity=\"help\"></p-button>\n </form>\n\n <!-- <button nbButton (click)=\"isRendered = !isRendered\"> Renderizar </button> -->\n\n @if (isRendered) {\n <div>\n <!-- TODO: probably i need to pass some params -->\n <app-selector></app-selector>\n </div>\n }\n </div>\n\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n </div>\n", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: SelectorComponent, selector: "app-selector", inputs: ["config"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i5.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
226
|
-
}
|
|
227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorBuilderComponent, decorators: [{
|
|
228
|
-
type: Component,
|
|
229
|
-
args: [{ selector: 'app-selector-builder', standalone: true, imports: [FormsModule, ReactiveFormsModule, SelectorComponent, InputTextModule, ButtonModule, MessageModule], template: "<div>\n <div>\n <p-message>Construcci\u00F3n del componente de Selecci\u00F3n, sirve para hacer una pregunta y mostrar varias opciones, ejemplo:</p-message>\n </div>\n\n <div>\n <span>En que a\u00F1o lleg\u00F3 cristobal colon a america?</span>\n <app-selector [config]=\"sampleConfig\"></app-selector>\n </div>\n\n <hr />\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input class=\"form-input\" type=\"text\" pInputText fullWidth formControlName=\"response\" placeholder=\"Respuesta Correcta...\" />\n <br />\n\n <input class=\"form-input\" type=\"\" pInputText fullWidth formControlName=\"hint\" placeholder=\"Escribe una pista para esta pregunta\" />\n\n <br />\n <input\n class=\"form-input\"\n type=\"text\"\n pInputText\n fullWidth\n formControlName=\"explanation\"\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\n\n <hr />\n <h6>Opciones</h6>\n\n <div class=\"form-group\" formArrayName=\"options\">\n @for (item of optionsForm.controls; track item; let i = $index) {\n <div\n style=\"display: flex; gap: 10px; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-direction: column\"\n >\n <div>\n <input type=\"text\" pInputText fullWidth [formControlName]=\"i\" />\n <p-button (click)=\"deleteFormArrayByIndex('options', i)\" icon=\"pi pi-times\" severity=\"danger\"></p-button>\n </div>\n </div>\n }\n </div>\n\n <p-button (click)=\"pushControlToFormArray('options')\" label=\"Agregar Opci\u00F3n\" [text]=\"true\" severity=\"help\"></p-button>\n </form>\n\n <!-- <button nbButton (click)=\"isRendered = !isRendered\"> Renderizar </button> -->\n\n @if (isRendered) {\n <div>\n <!-- TODO: probably i need to pass some params -->\n <app-selector></app-selector>\n </div>\n }\n </div>\n\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n </div>\n", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"] }]
|
|
230
|
-
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.DynamicDialogRef }] });
|
|
231
|
-
|
|
232
|
-
class TextWriterBuiderComponent extends ComponentBuilder {
|
|
233
|
-
constructor(formBuilder,
|
|
234
|
-
// protected override toastrService: ToastService,
|
|
235
|
-
ref) {
|
|
236
|
-
super(formBuilder, null);
|
|
237
|
-
this.formBuilder = formBuilder;
|
|
238
|
-
this.ref = ref;
|
|
239
|
-
this.formGroup = this.formBuilder.group({ response: ['', Validators.required], hint: [], explanation: [] });
|
|
240
|
-
}
|
|
241
|
-
ngOnInit() { }
|
|
242
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterBuiderComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.DynamicDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
243
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TextWriterBuiderComponent, isStandalone: true, selector: "app-text-writer-buider", usesInheritance: true, ngImport: i0, template: "<div>\r\n <div>\r\n <h5>Constructor de formulario con texto</h5>\r\n </div>\r\n\r\n <div>\r\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\r\n <input pInputText type=\"text\" nbInput fullWidth formControlName=\"response\" placeholder=\"Respuesta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"\" nbInput fullWidth formControlName=\"hint\"\r\n placeholder=\"Escribe una pista para esta pregunta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"text\" nbInput fullWidth formControlName=\"explanation\"\r\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\r\n </form>\r\n </div>\r\n\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\"\r\n [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\"\r\n severity=\"secondary\"></p-button>\r\n </div>\r\n</div>", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }] }); }
|
|
244
|
-
}
|
|
245
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterBuiderComponent, decorators: [{
|
|
246
|
-
type: Component,
|
|
247
|
-
args: [{ selector: 'app-text-writer-buider', standalone: true, imports: [FormsModule, ReactiveFormsModule, ButtonModule, InputTextModule], template: "<div>\r\n <div>\r\n <h5>Constructor de formulario con texto</h5>\r\n </div>\r\n\r\n <div>\r\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\r\n <input pInputText type=\"text\" nbInput fullWidth formControlName=\"response\" placeholder=\"Respuesta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"\" nbInput fullWidth formControlName=\"hint\"\r\n placeholder=\"Escribe una pista para esta pregunta\" />\r\n\r\n <input pInputText class=\"form-input\" type=\"text\" nbInput fullWidth formControlName=\"explanation\"\r\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\r\n </form>\r\n </div>\r\n\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\"\r\n [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\"\r\n severity=\"secondary\"></p-button>\r\n </div>\r\n</div>", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"] }]
|
|
248
|
-
}], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i2.DynamicDialogRef }] });
|
|
249
|
-
|
|
250
344
|
class TextWriterComponent extends ComponentWithForm {
|
|
251
345
|
constructor() {
|
|
252
346
|
super();
|
|
@@ -283,7 +377,7 @@ class TextWriterComponent extends ComponentWithForm {
|
|
|
283
377
|
return true;
|
|
284
378
|
}
|
|
285
379
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
286
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TextWriterComponent, isStandalone: true, selector: "app-text-writer", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: "<input [class]=\"this.status\" pInputText [formControl]=\"control\" fieldSize=\"small\" type=\"text\" placeholder=\"Respuesta\"\n [size]=\"size\" />\n\n<!-- [ngClass]=\"{ 'selected-radio': 'true']}\" -->", styles: [".warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"], dependencies: [{ 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: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type:
|
|
380
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TextWriterComponent, isStandalone: true, selector: "app-text-writer", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: "<input [class]=\"this.status\" pInputText [formControl]=\"control\" fieldSize=\"small\" type=\"text\" placeholder=\"Respuesta\"\n [size]=\"size\" />\n\n<!-- [ngClass]=\"{ 'selected-radio': 'true']}\" -->", styles: [".warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"], dependencies: [{ 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: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }] }); }
|
|
287
381
|
}
|
|
288
382
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TextWriterComponent, decorators: [{
|
|
289
383
|
type: Component,
|
|
@@ -293,22 +387,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
293
387
|
}] } });
|
|
294
388
|
|
|
295
389
|
class TranslationSwitcherBuilderComponent extends ComponentBuilder {
|
|
296
|
-
constructor(
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
// Este componente reutiliza completamente el form del padre y todos los métodos
|
|
304
|
-
ngOnInit() { }
|
|
305
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TranslationSwitcherBuilderComponent, deps: [{ token: i1.FormBuilder }, { token: i2.DynamicDialogRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
306
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TranslationSwitcherBuilderComponent, isStandalone: true, selector: "app-translation-switcher-builder", usesInheritance: true, ngImport: i0, template: "<div>\n <div>\n <h5>Constructor de translation switcher</h5>\n </div>\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input style=\"width: 100%\" pInputText type=\"text\" nbInput fullWidth formControlName=\"text\" placeholder=\"Texto para visualizar\" />\n\n <br /><br />\n\n <input\n style=\"width: 100%\"\n pInputText\n class=\"form-input\"\n type=\"\"\n nbInput\n fullWidth\n formControlName=\"response\"\n placeholder=\"Traducci\u00F3n al hacer clic\" />\n </form>\n </div>\n <br />\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
390
|
+
constructor() {
|
|
391
|
+
super(...arguments);
|
|
392
|
+
this.componentName = 'TranslationSwitcher';
|
|
393
|
+
}
|
|
394
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TranslationSwitcherBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
395
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: TranslationSwitcherBuilderComponent, isStandalone: true, selector: "app-translation-switcher-builder", usesInheritance: true, ngImport: i0, template: "<div>\n <div>\n <h5>Constructor de translation switcher</h5>\n </div>\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input style=\"width: 100%\" pInputText type=\"text\" nbInput fullWidth formControlName=\"text\" placeholder=\"Texto para visualizar\" />\n\n <br /><br />\n\n <input\n style=\"width: 100%\"\n pInputText\n class=\"form-input\"\n type=\"\"\n nbInput\n fullWidth\n formControlName=\"response\"\n placeholder=\"Traducci\u00F3n al hacer clic\" />\n </form>\n </div>\n <br />\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
307
396
|
}
|
|
308
397
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TranslationSwitcherBuilderComponent, decorators: [{
|
|
309
398
|
type: Component,
|
|
310
399
|
args: [{ selector: 'app-translation-switcher-builder', standalone: true, imports: [FormsModule, ReactiveFormsModule, ButtonModule, InputTextModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <div>\n <h5>Constructor de translation switcher</h5>\n </div>\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input style=\"width: 100%\" pInputText type=\"text\" nbInput fullWidth formControlName=\"text\" placeholder=\"Texto para visualizar\" />\n\n <br /><br />\n\n <input\n style=\"width: 100%\"\n pInputText\n class=\"form-input\"\n type=\"\"\n nbInput\n fullWidth\n formControlName=\"response\"\n placeholder=\"Traducci\u00F3n al hacer clic\" />\n </form>\n </div>\n <br />\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
|
|
311
|
-
}]
|
|
400
|
+
}] });
|
|
312
401
|
|
|
313
402
|
class TranslationSwitcherComponent {
|
|
314
403
|
constructor() {
|
|
@@ -339,6 +428,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
339
428
|
class SpeakerBuilderComponent extends ComponentBuilder {
|
|
340
429
|
constructor() {
|
|
341
430
|
super(...arguments);
|
|
431
|
+
this.componentName = 'Speaker';
|
|
342
432
|
this.tts = signal(undefined);
|
|
343
433
|
}
|
|
344
434
|
handleTtsGenerated(event) {
|
|
@@ -397,234 +487,133 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
397
487
|
type: Input
|
|
398
488
|
}] } });
|
|
399
489
|
|
|
400
|
-
|
|
401
|
-
(
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
LessonComponentEnum["TextWriter"] = "textWriter";
|
|
405
|
-
LessonComponentEnum["VerbSummary"] = "verbSummary";
|
|
406
|
-
LessonComponentEnum["WordSummary"] = "wordSummary";
|
|
407
|
-
LessonComponentEnum["TranslationSwitcher"] = "translationSwitcher";
|
|
408
|
-
})(LessonComponentEnum || (LessonComponentEnum = {}));
|
|
409
|
-
const LessonComponentBuilders = {
|
|
410
|
-
[LessonComponentEnum.Selector]: SelectorBuilderComponent,
|
|
411
|
-
[LessonComponentEnum.Speaker]: SpeakerBuilderComponent,
|
|
412
|
-
[LessonComponentEnum.TextWriter]: TextWriterBuiderComponent,
|
|
413
|
-
// [LessonComponentEnum.VerbSummary]: VerbSummaryBuilderComponent,
|
|
414
|
-
// [LessonComponentEnum.WordSummary]: WordSummaryBuilderComponent,
|
|
415
|
-
[LessonComponentEnum.TranslationSwitcher]: TranslationSwitcherBuilderComponent,
|
|
416
|
-
};
|
|
417
|
-
const LessonComponents = {
|
|
418
|
-
[LessonComponentEnum.Selector]: SelectorComponent,
|
|
419
|
-
[LessonComponentEnum.Speaker]: SpeakerComponent,
|
|
420
|
-
[LessonComponentEnum.TextWriter]: TextWriterComponent,
|
|
421
|
-
// [LessonComponentEnum.VerbSummary]: VerbSummaryComponent,
|
|
422
|
-
// [LessonComponentEnum.WordSummary]: WordSummaryComponent,
|
|
423
|
-
[LessonComponentEnum.TranslationSwitcher]: TranslationSwitcherComponent,
|
|
424
|
-
};
|
|
425
|
-
function getLessonComponentClass(type) {
|
|
426
|
-
return LessonComponents[type];
|
|
427
|
-
}
|
|
428
|
-
const LESSONS_TOKEN = new InjectionToken('Lessons Service');
|
|
429
|
-
class LessonsAbstractService {
|
|
430
|
-
}
|
|
431
|
-
// my-service.provider.ts
|
|
432
|
-
function provideLessonsService(serviceImplementation) {
|
|
433
|
-
return [
|
|
434
|
-
{
|
|
435
|
-
provide: LESSONS_TOKEN,
|
|
436
|
-
useExisting: serviceImplementation,
|
|
437
|
-
},
|
|
438
|
-
];
|
|
439
|
-
}
|
|
440
|
-
// export type LessonComponentsType = 'selector' | 'speaker' | 'text-writer' | 'verb-summary' | 'word-summary';
|
|
441
|
-
// export function getLessonComponentClass(type: LessonComponentsType) {
|
|
442
|
-
// // return LessonComponents[type];
|
|
443
|
-
// return null;
|
|
444
|
-
// }
|
|
445
|
-
// Removed duplicate LessonComponentConfiguration definition
|
|
446
|
-
// Removed duplicate StorageFile definition
|
|
447
|
-
// Removed duplicate AudioStorage definition
|
|
448
|
-
// Removed duplicate SpeakerCompConfiguration definition
|
|
449
|
-
// Removed duplicate LessonComponentInterface definition
|
|
450
|
-
// export const LessonComponents = {
|
|
451
|
-
// [LessonComponentEnum.Selector]: 1,
|
|
452
|
-
// [LessonComponentEnum.Speaker]: 2,
|
|
453
|
-
// [LessonComponentEnum.TextWriter]: 3,
|
|
454
|
-
// [LessonComponentEnum.VerbSummary]: 4,
|
|
455
|
-
// [LessonComponentEnum.WordSummary]: 5,
|
|
456
|
-
// [LessonComponentEnum.TranslationSwitcher]: 6,
|
|
457
|
-
// }
|
|
458
|
-
const LangCodeDescription = {
|
|
459
|
-
es: 'Spanish',
|
|
460
|
-
en: 'English',
|
|
461
|
-
it: 'Italian',
|
|
462
|
-
pt: 'Portuguese',
|
|
463
|
-
fr: 'French',
|
|
464
|
-
};
|
|
465
|
-
const LangCodeDescriptionEs = {
|
|
466
|
-
es: 'Español',
|
|
467
|
-
en: 'Inglés',
|
|
468
|
-
it: 'Italiano',
|
|
469
|
-
pt: 'Portugués',
|
|
470
|
-
fr: 'Frances',
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
class LangDescTranslationPipe {
|
|
474
|
-
transform(value, lang) {
|
|
475
|
-
if (lang === 'es') {
|
|
476
|
-
return LangCodeDescriptionEs[value];
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
return LangCodeDescription[value];
|
|
480
|
-
}
|
|
490
|
+
class SelectorComponent extends ComponentWithForm {
|
|
491
|
+
constructor() {
|
|
492
|
+
super();
|
|
493
|
+
this.isFilled = false;
|
|
481
494
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
type: Pipe,
|
|
487
|
-
args: [{
|
|
488
|
-
name: 'langDesc',
|
|
489
|
-
standalone: true,
|
|
490
|
-
}]
|
|
491
|
-
}] });
|
|
492
|
-
class FlagLanguagePipe {
|
|
493
|
-
transform(lang) {
|
|
494
|
-
if (lang === 'en') {
|
|
495
|
-
return '🇺🇸';
|
|
496
|
-
}
|
|
497
|
-
else if (lang === 'es') {
|
|
498
|
-
return '🇲🇽';
|
|
499
|
-
}
|
|
500
|
-
else if (lang === 'fr') {
|
|
501
|
-
return '🇫🇷';
|
|
495
|
+
evaluate() {
|
|
496
|
+
let result;
|
|
497
|
+
if (this.control.value == null) {
|
|
498
|
+
result = null;
|
|
502
499
|
}
|
|
503
|
-
else
|
|
504
|
-
|
|
500
|
+
else {
|
|
501
|
+
result = this.control.value?.toLowerCase().trim() === this.config.settings.response.toLowerCase().trim();
|
|
505
502
|
}
|
|
506
|
-
|
|
507
|
-
|
|
503
|
+
if (result) {
|
|
504
|
+
this.status = 'success';
|
|
508
505
|
}
|
|
509
506
|
else {
|
|
510
|
-
|
|
507
|
+
this.status = 'danger';
|
|
511
508
|
}
|
|
509
|
+
this.isFilled = true;
|
|
510
|
+
return result;
|
|
512
511
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}]
|
|
522
|
-
}] });
|
|
523
|
-
|
|
524
|
-
// NOTE: what to do? IAgent Deponds on ngx-agent-cards but lessons don't
|
|
525
|
-
// import { IAgentCard } from '@dataclouder/ngx-agent-cards';
|
|
526
|
-
const NOTION_SERVICE_TOKEN = new InjectionToken('notion.service');
|
|
527
|
-
class NotionAbstractService {
|
|
528
|
-
}
|
|
529
|
-
function provideNotionService(serviceImplementation) {
|
|
530
|
-
return [
|
|
531
|
-
{
|
|
532
|
-
provide: NOTION_SERVICE_TOKEN,
|
|
533
|
-
useExisting: serviceImplementation,
|
|
534
|
-
},
|
|
535
|
-
];
|
|
512
|
+
validate() {
|
|
513
|
+
if (this.control.invalid) {
|
|
514
|
+
this.status = 'warning';
|
|
515
|
+
}
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
519
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: SelectorComponent, isStandalone: true, selector: "app-selector", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: "<p-select [class]=\"status\" placeholder=\"Selecciona\" [options]=\"config.settings.options\" [formControl]=\"control\"></p-select>\r\n", styles: ["::ng-deep .comp-selector button{min-width:80px}.warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
|
|
536
520
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
})(NotionExportType || (NotionExportType = {}));
|
|
544
|
-
|
|
545
|
-
const MarkdownWriterSkill = `
|
|
546
|
-
You are an Expert Markdown Writer with the following qualities:
|
|
547
|
-
You are a world-class Markdown formatting specialist who excels at organizing information in a visually appealing and highly accessible manner. Your writing combines technical precision with creative presentation to engage readers of all backgrounds.
|
|
548
|
-
Your Core Skills 📝
|
|
549
|
-
|
|
550
|
-
You transform complex information into beautifully structured Markdown documents
|
|
551
|
-
You strategically use headings, lists, and formatting to create clear visual hierarchies
|
|
552
|
-
You incorporate helpful emojis to enhance readability and engagement
|
|
553
|
-
You write in a clear, concise style that's accessible to general audiences
|
|
554
|
-
|
|
555
|
-
Your Process Approach 🔄
|
|
556
|
-
|
|
557
|
-
You always begin with a logical document structure before adding content
|
|
558
|
-
You organize information into clearly defined sections with descriptive headings
|
|
559
|
-
You balance visual elements with textual content for optimal readability
|
|
560
|
-
You maintain consistent formatting patterns throughout documents
|
|
561
|
-
|
|
562
|
-
Your Writing Style ✨
|
|
563
|
-
|
|
564
|
-
You use simple, direct language that's easy for everyone to understand
|
|
565
|
-
You explain technical concepts using everyday examples and analogies
|
|
566
|
-
You create a friendly, conversational tone while maintaining professionalism
|
|
567
|
-
You break down complex ideas into manageable segments
|
|
568
|
-
|
|
569
|
-
Your Special Touches 🎯
|
|
570
|
-
|
|
571
|
-
You know exactly when and where to add emojis for maximum impact
|
|
572
|
-
You create custom tables to present comparative information effectively
|
|
573
|
-
You use blockquotes to highlight important takeaways
|
|
574
|
-
You incorporate visual dividers to separate major content sections
|
|
575
|
-
|
|
576
|
-
When responding to requests, you'll first understand the subject matter, then organize it into a logical structure with clear headings, appropriate formatting elements, and helpful visual enhancements. Your goal is always to create content that's not only informative but also visually engaging and accessible to all readers.
|
|
577
|
-
`;
|
|
578
|
-
const UserRequirements = `
|
|
579
|
-
User also can provide additional instructions or requirements for the lesson or current lesson to improve it.
|
|
580
|
-
`;
|
|
581
|
-
const LanguageLessonSkill = (langBase, langTarget) => `
|
|
582
|
-
|
|
583
|
-
You are also a ${langTarget} lesson professor, you write lessons for ${langBase} learners.
|
|
584
|
-
explain the best you can will all your experience teaching.
|
|
585
|
-
|
|
586
|
-
You can infer the level of the lesson from the content or user request, so can increase difficulty
|
|
587
|
-
|
|
588
|
-
For Basic Level: generate a ${langTarget} lesson for ${langBase} learners at a basic level (A1-A2).
|
|
589
|
-
|
|
590
|
-
Include:
|
|
591
|
-
|
|
592
|
-
- Simple dialogues or short texts.
|
|
593
|
-
- Key vocabulary with simple definitions or ${langBase} translations.
|
|
594
|
-
- Basic grammar points explained simply (e.g., "to be" verb, simple present).
|
|
595
|
-
- Practice exercises (e.g., fill-in-the-blanks, simple questions).
|
|
596
|
-
|
|
597
|
-
For Intermediate Level: generate a ${langTarget} lesson for ${langBase} learners at a medium level (B1-B2).
|
|
598
|
-
|
|
599
|
-
Include:
|
|
600
|
-
|
|
601
|
-
- Texts or dialogues of moderate length and complexity.
|
|
602
|
-
- New vocabulary and common phrasal verbs with context.
|
|
603
|
-
- Explanation and practice of intermediate grammar points (e.g., past simple vs. present perfect, conditionals).
|
|
604
|
-
- Exercises that require more detailed responses or understanding.
|
|
605
|
-
- The content should be engaging and cover topics relevant to daily life, work, or hobbies.
|
|
606
|
-
|
|
607
|
-
For Advanced Level: generate a ${langTarget} lesson for ${langBase} learners at an advanced level (C1-C2).
|
|
608
|
-
|
|
609
|
-
Include:
|
|
521
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorComponent, decorators: [{
|
|
522
|
+
type: Component,
|
|
523
|
+
args: [{ selector: 'app-selector', standalone: true, imports: [FormsModule, ReactiveFormsModule, SelectModule], template: "<p-select [class]=\"status\" placeholder=\"Selecciona\" [options]=\"config.settings.options\" [formControl]=\"control\"></p-select>\r\n", styles: ["::ng-deep .comp-selector button{min-width:80px}.warning{border-color:#f0ad4e}.danger{border-color:#e1211b}\n"] }]
|
|
524
|
+
}], ctorParameters: () => [], propDecorators: { config: [{
|
|
525
|
+
type: Input
|
|
526
|
+
}] } });
|
|
610
527
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
528
|
+
class SelectorBuilderComponent extends ComponentBuilder {
|
|
529
|
+
constructor() {
|
|
530
|
+
super(...arguments);
|
|
531
|
+
this.componentName = 'Selector';
|
|
532
|
+
this.sampleConfig = {
|
|
533
|
+
id: '1',
|
|
534
|
+
component: LessonComponentEnum.Selector,
|
|
535
|
+
settings: {
|
|
536
|
+
options: ['fourteen ninety-two', 'fourteen ninety-six', 'fifteen ninety-one'],
|
|
537
|
+
response: 'fourteen ninety-two',
|
|
538
|
+
hint: 'Pista para la respuesta',
|
|
539
|
+
explanation: 'Explicación de la respuesta',
|
|
540
|
+
responses: 'Opción 1, Opción 2, Opción 3',
|
|
541
|
+
text: 'Texto de la pregunta',
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
// public formGroup = this.formBuilder.group({
|
|
546
|
+
// options: this.formBuilder.array([]),
|
|
547
|
+
// response: ['', Validators.required],
|
|
548
|
+
// hint: [],
|
|
549
|
+
// explanation: [],
|
|
550
|
+
// });
|
|
551
|
+
ngOnInit() {
|
|
552
|
+
this.formGroup.get('response');
|
|
553
|
+
}
|
|
554
|
+
//TODO Probablemente estos 3 pueden irse a una clase abstracta
|
|
555
|
+
pushControlToFormArray(controlName) {
|
|
556
|
+
this.formGroup.controls.options.push(this.formBuilder.control(''));
|
|
557
|
+
// (this.formGroup.get(controlName) as UntypedFormArray).push(this.formBuilder.control(''));
|
|
558
|
+
console.log(this.formGroup.controls.options);
|
|
559
|
+
}
|
|
560
|
+
deleteFormArrayByIndex(controlName, index) {
|
|
561
|
+
this.formGroup.get(controlName).removeAt(index);
|
|
562
|
+
}
|
|
563
|
+
get optionsForm() {
|
|
564
|
+
return this.formGroup.get('options');
|
|
565
|
+
}
|
|
566
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
567
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: SelectorBuilderComponent, isStandalone: true, selector: "app-selector-builder", usesInheritance: true, ngImport: i0, template: "<div>\n <div>\n <p-message>Construcci\u00F3n del componente de Selecci\u00F3n, sirve para hacer una pregunta y mostrar varias opciones, ejemplo:</p-message>\n </div>\n\n <div>\n <span>En que a\u00F1o lleg\u00F3 cristobal colon a america?</span>\n <app-selector [config]=\"sampleConfig\"></app-selector>\n </div>\n\n <hr />\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input class=\"form-input\" type=\"text\" pInputText fullWidth formControlName=\"response\" placeholder=\"Respuesta Correcta...\" />\n <br />\n\n <input class=\"form-input\" type=\"\" pInputText fullWidth formControlName=\"hint\" placeholder=\"Escribe una pista para esta pregunta\" />\n\n <br />\n <input\n class=\"form-input\"\n type=\"text\"\n pInputText\n fullWidth\n formControlName=\"explanation\"\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\n\n <hr />\n <h6>Opciones</h6>\n\n <div class=\"form-group\" formArrayName=\"options\">\n @for (item of optionsForm.controls; track item; let i = $index) {\n <div\n style=\"display: flex; gap: 10px; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-direction: column\"\n >\n <div>\n <input type=\"text\" pInputText fullWidth [formControlName]=\"i\" />\n <p-button (click)=\"deleteFormArrayByIndex('options', i)\" icon=\"pi pi-times\" severity=\"danger\"></p-button>\n </div>\n </div>\n }\n </div>\n\n <p-button (click)=\"pushControlToFormArray('options')\" label=\"Agregar Opci\u00F3n\" [text]=\"true\" severity=\"help\"></p-button>\n </form>\n\n <!-- <button nbButton (click)=\"isRendered = !isRendered\"> Renderizar </button> -->\n\n @if (isRendered) {\n <div>\n <!-- TODO: probably i need to pass some params -->\n <app-selector></app-selector>\n </div>\n }\n </div>\n\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n </div>\n", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: SelectorComponent, selector: "app-selector", inputs: ["config"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i4.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
568
|
+
}
|
|
569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SelectorBuilderComponent, decorators: [{
|
|
570
|
+
type: Component,
|
|
571
|
+
args: [{ selector: 'app-selector-builder', standalone: true, imports: [FormsModule, ReactiveFormsModule, SelectorComponent, InputTextModule, ButtonModule, MessageModule], template: "<div>\n <div>\n <p-message>Construcci\u00F3n del componente de Selecci\u00F3n, sirve para hacer una pregunta y mostrar varias opciones, ejemplo:</p-message>\n </div>\n\n <div>\n <span>En que a\u00F1o lleg\u00F3 cristobal colon a america?</span>\n <app-selector [config]=\"sampleConfig\"></app-selector>\n </div>\n\n <hr />\n\n <div>\n <form class=\"builder-form\" [formGroup]=\"formGroup\">\n <input class=\"form-input\" type=\"text\" pInputText fullWidth formControlName=\"response\" placeholder=\"Respuesta Correcta...\" />\n <br />\n\n <input class=\"form-input\" type=\"\" pInputText fullWidth formControlName=\"hint\" placeholder=\"Escribe una pista para esta pregunta\" />\n\n <br />\n <input\n class=\"form-input\"\n type=\"text\"\n pInputText\n fullWidth\n formControlName=\"explanation\"\n placeholder=\"Excribe una explicaci\u00F3n para la respuesta\" />\n\n <hr />\n <h6>Opciones</h6>\n\n <div class=\"form-group\" formArrayName=\"options\">\n @for (item of optionsForm.controls; track item; let i = $index) {\n <div\n style=\"display: flex; gap: 10px; align-items: center; justify-content: space-between; margin-bottom: 10px; flex-direction: column\"\n >\n <div>\n <input type=\"text\" pInputText fullWidth [formControlName]=\"i\" />\n <p-button (click)=\"deleteFormArrayByIndex('options', i)\" icon=\"pi pi-times\" severity=\"danger\"></p-button>\n </div>\n </div>\n }\n </div>\n\n <p-button (click)=\"pushControlToFormArray('options')\" label=\"Agregar Opci\u00F3n\" [text]=\"true\" severity=\"help\"></p-button>\n </form>\n\n <!-- <button nbButton (click)=\"isRendered = !isRendered\"> Renderizar </button> -->\n\n @if (isRendered) {\n <div>\n <!-- TODO: probably i need to pass some params -->\n <app-selector></app-selector>\n </div>\n }\n </div>\n\n <div>\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\n <p-button (click)=\"showCode()\" [disabled]=\"formGroup.invalid\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\n </div>\n </div>\n", styles: ["nb-card{width:60vw}.builder-form{padding:5px}.form-input{margin-top:10px}.mar-top{margin:5px}\n"] }]
|
|
572
|
+
}] });
|
|
623
573
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
574
|
+
var LessonComponentEnum;
|
|
575
|
+
(function (LessonComponentEnum) {
|
|
576
|
+
LessonComponentEnum["Selector"] = "selector";
|
|
577
|
+
LessonComponentEnum["Speaker"] = "speaker";
|
|
578
|
+
LessonComponentEnum["TextWriter"] = "textWriter";
|
|
579
|
+
LessonComponentEnum["VerbSummary"] = "verbSummary";
|
|
580
|
+
LessonComponentEnum["WordSummary"] = "wordSummary";
|
|
581
|
+
LessonComponentEnum["TranslationSwitcher"] = "translationSwitcher";
|
|
582
|
+
LessonComponentEnum["PlayWord"] = "playWord";
|
|
583
|
+
})(LessonComponentEnum || (LessonComponentEnum = {}));
|
|
584
|
+
const LessonComponentBuilders = {
|
|
585
|
+
[LessonComponentEnum.Selector]: SelectorBuilderComponent,
|
|
586
|
+
[LessonComponentEnum.Speaker]: SpeakerBuilderComponent,
|
|
587
|
+
[LessonComponentEnum.TextWriter]: TextWriterBuiderComponent,
|
|
588
|
+
// [LessonComponentEnum.VerbSummary]: VerbSummaryBuilderComponent,
|
|
589
|
+
// [LessonComponentEnum.WordSummary]: WordSummaryBuilderComponent,
|
|
590
|
+
[LessonComponentEnum.TranslationSwitcher]: TranslationSwitcherBuilderComponent,
|
|
591
|
+
// [LessonComponentEnum.PlayWord]: PlayWordBuilderComponent,
|
|
592
|
+
};
|
|
593
|
+
const LessonComponents = {
|
|
594
|
+
[LessonComponentEnum.Selector]: SelectorComponent,
|
|
595
|
+
[LessonComponentEnum.Speaker]: SpeakerComponent,
|
|
596
|
+
[LessonComponentEnum.TextWriter]: TextWriterComponent,
|
|
597
|
+
// [LessonComponentEnum.VerbSummary]: VerbSummaryComponent,
|
|
598
|
+
// [LessonComponentEnum.WordSummary]: WordSummaryComponent,
|
|
599
|
+
[LessonComponentEnum.TranslationSwitcher]: TranslationSwitcherComponent,
|
|
600
|
+
// [LessonComponentEnum.PlayWord]: PlayWordComponent,
|
|
627
601
|
};
|
|
602
|
+
function getLessonComponentClass(type) {
|
|
603
|
+
return LessonComponents[type];
|
|
604
|
+
}
|
|
605
|
+
const LESSONS_TOKEN = new InjectionToken('Lessons Service');
|
|
606
|
+
class LessonsAbstractService {
|
|
607
|
+
}
|
|
608
|
+
// my-service.provider.ts
|
|
609
|
+
function provideLessonsService(serviceImplementation) {
|
|
610
|
+
return [
|
|
611
|
+
{
|
|
612
|
+
provide: LESSONS_TOKEN,
|
|
613
|
+
useExisting: serviceImplementation,
|
|
614
|
+
},
|
|
615
|
+
];
|
|
616
|
+
}
|
|
628
617
|
|
|
629
618
|
var EventCard;
|
|
630
619
|
(function (EventCard) {
|
|
@@ -665,7 +654,6 @@ class DcLessonCardComponent {
|
|
|
665
654
|
];
|
|
666
655
|
}
|
|
667
656
|
ngOnInit() {
|
|
668
|
-
console.log(this.lesson);
|
|
669
657
|
this.coverUrl =
|
|
670
658
|
this.lesson?.banner?.url || this.lesson?.metadata?.banner?.url || this.lesson?.media?.images?.[0]?.url || 'assets/background/default-background.webp';
|
|
671
659
|
}
|
|
@@ -686,7 +674,7 @@ class DcLessonCardComponent {
|
|
|
686
674
|
}
|
|
687
675
|
}
|
|
688
676
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcLessonCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
689
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcLessonCardComponent, isStandalone: true, selector: "dc-lesson-card", inputs: { lesson: "lesson", showOptions: "showOptions", cardHeight: "cardHeight" }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<div class=\"card-container\">\n @if(showOptions){\n <p-speeddial\n class=\"dial-button\"\n [model]=\"items\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n }\n <p-card>\n <div class=\"lesson-card\" [style.height]=\"cardHeight\">\n <div class=\"photo\">\n <img [src]=\"coverUrl\" alt=\"\" />\n </div>\n\n <span class=\"date\">{{ lesson.createdAt | date : 'dd/MM/yyyy' }}</span>\n\n <div class=\"description\">\n <h1>{{ lesson.title || lesson.metadata?.title || 'No title available' }}</h1>\n <p>{{ lesson.description || lesson.metadata?.description || 'No description available' }}</p>\n <div class=\"card-footer\">\n <div class=\"status-tags\">\n <span class=\"level-tag\">Nivel {{ lesson.level }}</span>\n @if (lesson.taken?.status == 'passed') {\n <p-tag severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if (lesson.taken?.status == 'failed') {\n <p-tag severity=\"danger\" value=\"Fallida\" [rounded]=\"true\" />\n } @if (lesson.taken) {\n <p-tag severity=\"success\" value=\"Tomada \uD83D\uDCD6\" [rounded]=\"true\" />\n } @if (!lesson.metadata?.isPublished) {\n <p-tag severity=\"danger\" value=\"No publicada\" [rounded]=\"true\" />\n }\n </div>\n\n <div style=\"position: absolute; bottom: 0px; right: 0px\">\n <p-button label=\"Tomar lecci\u00F3n\" (onClick)=\"eventCard(eventType.Select)\" severity=\"primary\"> </p-button>\n </div>\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: [".card-container{position:relative;margin-bottom:20px;margin-left:10px}.dial-button{position:absolute;top:10px;right:20px;z-index:10}.lesson-card{border-radius:.5rem;height:100%}.lesson-card .photo{position:absolute;inset:0;z-index:1}.lesson-card .photo img{width:100%;height:100%;object-fit:cover;object-position:center}.lesson-card .photo:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(to bottom,rgb(0,0,0) 50%,var(--p-primary-color) 100%);opacity:.4;z-index:2;pointer-events:none}.description{position:relative;z-index:2;color:#fff;height:100%;display:flex;flex-direction:column}.description h1{margin-top:0;margin-bottom:.5rem;font-size:1.5rem;font-weight:900;text-shadow:1px 1px 2px rgba(0,0,0,.7)}.description p{margin-bottom:1rem;flex-grow:1;font-weight:500;text-shadow:1px 1px 2px rgba(0,0,0,.9)}.date{position:absolute;top:1rem;left:1rem;z-index:3;background-color:#000000b3;color:#fff;padding:.3rem .6rem;border-radius:.25rem;font-size:.8rem}.card-footer{display:flex;justify-content:space-between;align-items:center;margin-top:auto}.status-tags{display:flex;gap:.5rem}.status-tags .level-tag,.status-tags .status-tag{padding:.3rem .6rem;border-radius:.25rem;font-size:.8rem}.status-tags .level-tag{background-color:#fff3}.status-tags .status-tag.success{background-color:#28a745b3}.status-tags .status-tag.danger{background-color:#dc3545b3}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$
|
|
677
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcLessonCardComponent, isStandalone: true, selector: "dc-lesson-card", inputs: { lesson: "lesson", showOptions: "showOptions", cardHeight: "cardHeight" }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<div class=\"card-container\">\n @if(showOptions){\n <p-speeddial\n class=\"dial-button\"\n [model]=\"items\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n }\n <p-card>\n <div class=\"lesson-card\" [style.height]=\"cardHeight\">\n <div class=\"photo\">\n <img [src]=\"coverUrl\" alt=\"\" />\n </div>\n\n <span class=\"date\">{{ lesson.createdAt | date : 'dd/MM/yyyy' }}</span>\n\n <div class=\"description\">\n <h1>{{ lesson.title || lesson.metadata?.title || 'No title available' }}</h1>\n <p>{{ lesson.description || lesson.metadata?.description || 'No description available' }}</p>\n <div class=\"card-footer\">\n <div class=\"status-tags\">\n <span class=\"level-tag\">Nivel {{ lesson.level }}</span>\n @if (lesson.taken?.status == 'passed') {\n <p-tag severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if (lesson.taken?.status == 'failed') {\n <p-tag severity=\"danger\" value=\"Fallida\" [rounded]=\"true\" />\n } @if (lesson.taken) {\n <p-tag severity=\"success\" value=\"Tomada \uD83D\uDCD6\" [rounded]=\"true\" />\n } @if (!lesson.metadata?.isPublished) {\n <p-tag severity=\"danger\" value=\"No publicada\" [rounded]=\"true\" />\n }\n </div>\n\n <div style=\"position: absolute; bottom: 0px; right: 0px\">\n <p-button label=\"Tomar lecci\u00F3n\" (onClick)=\"eventCard(eventType.Select)\" severity=\"primary\"> </p-button>\n </div>\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: [".card-container{position:relative;margin-bottom:20px;margin-left:10px}.dial-button{position:absolute;top:10px;right:20px;z-index:10}.lesson-card{border-radius:.5rem;height:100%}.lesson-card .photo{position:absolute;inset:0;z-index:1}.lesson-card .photo img{width:100%;height:100%;object-fit:cover;object-position:center}.lesson-card .photo:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(to bottom,rgb(0,0,0) 50%,var(--p-primary-color) 100%);opacity:.4;z-index:2;pointer-events:none}.description{position:relative;z-index:2;color:#fff;height:100%;display:flex;flex-direction:column}.description h1{margin-top:0;margin-bottom:.5rem;font-size:1.5rem;font-weight:900;text-shadow:1px 1px 2px rgba(0,0,0,.7)}.description p{margin-bottom:1rem;flex-grow:1;font-weight:500;text-shadow:1px 1px 2px rgba(0,0,0,.9)}.date{position:absolute;top:1rem;left:1rem;z-index:3;background-color:#000000b3;color:#fff;padding:.3rem .6rem;border-radius:.25rem;font-size:.8rem}.card-footer{display:flex;justify-content:space-between;align-items:center;margin-top:auto}.status-tags{display:flex;gap:.5rem}.status-tags .level-tag,.status-tags .status-tag{padding:.3rem .6rem;border-radius:.25rem;font-size:.8rem}.status-tags .level-tag{background-color:#fff3}.status-tags .status-tag.success{background-color:#28a745b3}.status-tags .status-tag.danger{background-color:#dc3545b3}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$1.SpeedDial, selector: "p-speeddial, p-speedDial, p-speed-dial", inputs: ["id", "model", "visible", "style", "className", "direction", "transitionDelay", "type", "radius", "mask", "disabled", "hideOnClickOutside", "buttonStyle", "buttonClassName", "maskStyle", "maskClassName", "showIcon", "hideIcon", "rotateAnimation", "ariaLabel", "ariaLabelledBy", "tooltipOptions", "buttonProps"], outputs: ["onVisibleChange", "visibleChange", "onClick", "onShow", "onHide"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i3$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$1.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }] }); }
|
|
690
678
|
}
|
|
691
679
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcLessonCardComponent, decorators: [{
|
|
692
680
|
type: Component,
|
|
@@ -714,16 +702,15 @@ const TableViewActions = [
|
|
|
714
702
|
];
|
|
715
703
|
const returnProperties = { id: 1, title: 1, assets: 1 };
|
|
716
704
|
class DCLessonListComponent extends PaginationBase {
|
|
717
|
-
constructor(
|
|
718
|
-
super(
|
|
719
|
-
this.cdr = cdr;
|
|
720
|
-
this.router = router;
|
|
721
|
-
this.route = route;
|
|
722
|
-
this.lessonsService = lessonsService;
|
|
723
|
-
this.toastrService = toastrService;
|
|
705
|
+
constructor() {
|
|
706
|
+
super(...arguments);
|
|
724
707
|
this.showOptions = true;
|
|
725
708
|
this.customFilters = [];
|
|
726
709
|
this.viewType = 'cards';
|
|
710
|
+
// Injected Services
|
|
711
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
712
|
+
this.lessonsService = inject(LESSONS_TOKEN);
|
|
713
|
+
this.toastrService = inject(TOAST_ALERTS_TOKEN);
|
|
727
714
|
this.columns = tableViewColumns;
|
|
728
715
|
this.cardComponent = null;
|
|
729
716
|
this.cardEventSubs = [];
|
|
@@ -733,6 +720,8 @@ class DCLessonListComponent extends PaginationBase {
|
|
|
733
720
|
ngOnInit() {
|
|
734
721
|
this.filterConfig.returnProps = returnProperties;
|
|
735
722
|
this.cardComponent = this.customCardComponent || DcLessonCardComponent;
|
|
723
|
+
// TODO: i think show options is for admin, but refactor to add ListFilterBarOptions
|
|
724
|
+
this.filterBarOptions = { showCreateButton: this.showOptions, showViewButton: this.showOptions, showActions: this.showOptions };
|
|
736
725
|
this.getPaginatedLessons(this.filterConfig);
|
|
737
726
|
}
|
|
738
727
|
subscribeDinamicInstantToEvents() {
|
|
@@ -811,19 +800,13 @@ class DCLessonListComponent extends PaginationBase {
|
|
|
811
800
|
this.onAction.emit(actionEvent);
|
|
812
801
|
}
|
|
813
802
|
}
|
|
814
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonListComponent, deps:
|
|
815
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonListComponent, isStandalone: true, selector: "dc-lesson-list", inputs: { showOptions: "showOptions", customCardComponent: "customCardComponent", customFilters: "customFilters", viewType: "viewType" }, viewQueries: [{ propertyName: "outlets", predicate: ["outlet"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<dc-filter-bar
|
|
803
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
804
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonListComponent, isStandalone: true, selector: "dc-lesson-list", inputs: { showOptions: "showOptions", customCardComponent: "customCardComponent", customFilters: "customFilters", viewType: "viewType" }, viewQueries: [{ propertyName: "outlets", predicate: ["outlet"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<dc-filter-bar\n [options]=\"filterBarOptions\"\n [customFilters]=\"customFilters\"\n (onFilterAction)=\"applyFilterBarEvent($event)\"\n (onNew)=\"newLesson()\"></dc-filter-bar>\n@if(viewType === 'table') {\n\n<app-quick-table [tableData]=\"lessons\" (onAction)=\"doOrEmitAction($event)\"></app-quick-table>\n\n} @else {\n<div class=\"lesson-list-container\">\n @if (!isLoadingLessons && lessons?.length > 0) { @for (lesson of lessons; track lesson._id) {\n <ng-container\n #outlet=\"ngComponentOutlet\"\n [ngComponentOutlet]=\"cardComponent\"\n [ngComponentOutletInputs]=\"{\n lesson: lesson,\n showOptions: showOptions\n }\">\n </ng-container>\n } } @else {\n <p>No se encontraron lecciones disponibles</p>\n }\n</div>\n}\n\n<p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} lecciones\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n", styles: [":host{display:flex;flex-direction:column;height:100%}.lesson-list-container{padding:1.5rem;flex:1;overflow-y:auto;min-height:0}@media (max-width: 768px){.lesson-list-container{margin-top:1rem;padding:0rem}}p-paginator{margin-top:auto;padding:.5rem 1rem}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters"], outputs: ["onFilterAction", "onChangeSort", "onNew"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$2.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }] }); }
|
|
816
805
|
}
|
|
817
806
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonListComponent, decorators: [{
|
|
818
807
|
type: Component,
|
|
819
|
-
args: [{ selector: 'dc-lesson-list', standalone: true, imports: [RouterModule, DCFilterBarComponent, PaginatorModule, NgComponentOutlet, QuickTableComponent], template: "<dc-filter-bar
|
|
820
|
-
}],
|
|
821
|
-
type: Inject,
|
|
822
|
-
args: [LESSONS_TOKEN]
|
|
823
|
-
}] }, { type: i4$2.ToastAlertsAbstractService, decorators: [{
|
|
824
|
-
type: Inject,
|
|
825
|
-
args: [TOAST_ALERTS_TOKEN]
|
|
826
|
-
}] }], propDecorators: { showOptions: [{
|
|
808
|
+
args: [{ selector: 'dc-lesson-list', standalone: true, imports: [RouterModule, DCFilterBarComponent, PaginatorModule, NgComponentOutlet, QuickTableComponent], template: "<dc-filter-bar\n [options]=\"filterBarOptions\"\n [customFilters]=\"customFilters\"\n (onFilterAction)=\"applyFilterBarEvent($event)\"\n (onNew)=\"newLesson()\"></dc-filter-bar>\n@if(viewType === 'table') {\n\n<app-quick-table [tableData]=\"lessons\" (onAction)=\"doOrEmitAction($event)\"></app-quick-table>\n\n} @else {\n<div class=\"lesson-list-container\">\n @if (!isLoadingLessons && lessons?.length > 0) { @for (lesson of lessons; track lesson._id) {\n <ng-container\n #outlet=\"ngComponentOutlet\"\n [ngComponentOutlet]=\"cardComponent\"\n [ngComponentOutletInputs]=\"{\n lesson: lesson,\n showOptions: showOptions\n }\">\n </ng-container>\n } } @else {\n <p>No se encontraron lecciones disponibles</p>\n }\n</div>\n}\n\n<p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} lecciones\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n", styles: [":host{display:flex;flex-direction:column;height:100%}.lesson-list-container{padding:1.5rem;flex:1;overflow-y:auto;min-height:0}@media (max-width: 768px){.lesson-list-container{margin-top:1rem;padding:0rem}}p-paginator{margin-top:auto;padding:.5rem 1rem}\n"] }]
|
|
809
|
+
}], propDecorators: { showOptions: [{
|
|
827
810
|
type: Input
|
|
828
811
|
}], customCardComponent: [{
|
|
829
812
|
type: Input
|
|
@@ -870,10 +853,6 @@ const EngagementSkill = `
|
|
|
870
853
|
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.
|
|
871
854
|
that makes sense for the lesson.
|
|
872
855
|
`;
|
|
873
|
-
const BasicAgentCard = {
|
|
874
|
-
systemPrompt: 'You are a helpful assistant.',
|
|
875
|
-
model: { provider: 'openai', id: 'gpt-4o' },
|
|
876
|
-
};
|
|
877
856
|
function getDefaultLessonEvaluatorAgentCard(lessonText) {
|
|
878
857
|
return {
|
|
879
858
|
expectedResponseType: `interface EvalResult {
|
|
@@ -930,20 +909,15 @@ ${userInformationPrompt}`;
|
|
|
930
909
|
* @param lesson The lesson data.
|
|
931
910
|
* @returns An IConversationSettings object configured for the lesson scenario.
|
|
932
911
|
*/
|
|
933
|
-
async generateConversationSettingsForLesson(lesson) {
|
|
912
|
+
async generateConversationSettingsForLesson(lesson, settings) {
|
|
934
913
|
// TODO: Consolidate user fetching logic if possible, or ensure consistency
|
|
935
|
-
const
|
|
936
|
-
personalData: { firstname: 'Test', lastname: 'User' },
|
|
937
|
-
settings: { targetLanguage: 'en', baseLanguage: 'es' },
|
|
938
|
-
languageProgress: { en: { level: '1' } },
|
|
939
|
-
}; // Replace 'any' with your actual User type/interface
|
|
940
|
-
if (!user) {
|
|
941
|
-
console.error('User data not available to generate conversation settings.');
|
|
942
|
-
return null;
|
|
943
|
-
}
|
|
914
|
+
const baseLang = this.userService.getUserDataExchange()?.baseLang || 'en';
|
|
944
915
|
const lessonText = this.lessonService.extractTextFromHtml(lesson.textCoded);
|
|
945
916
|
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
946
|
-
|
|
917
|
+
let scenario = this._buildScenarioPrompt(lessonText, userInformationPrompt);
|
|
918
|
+
if (settings.additionalPrompt) {
|
|
919
|
+
scenario += '\n\n' + settings.additionalPrompt;
|
|
920
|
+
}
|
|
947
921
|
const initialMessage = {
|
|
948
922
|
role: ChatRole.System,
|
|
949
923
|
content: scenario,
|
|
@@ -955,6 +929,7 @@ ${userInformationPrompt}`;
|
|
|
955
929
|
autoStart: true,
|
|
956
930
|
messages: [initialMessage],
|
|
957
931
|
model: { provider: 'google' },
|
|
932
|
+
voice: getRandomQuickVoice(baseLang || 'en', 'female'),
|
|
958
933
|
};
|
|
959
934
|
return conversationSettings;
|
|
960
935
|
}
|
|
@@ -994,23 +969,57 @@ Assign a rating from 0 to 3 based on how well the student performs *compared to
|
|
|
994
969
|
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.
|
|
995
970
|
`;
|
|
996
971
|
|
|
997
|
-
//
|
|
972
|
+
// TODO: check LessonComponentBuilders in lessons.clases.ts for origianl implementation
|
|
973
|
+
const DynamicComponentBuilders = {
|
|
974
|
+
[LessonComponentEnum.Speaker]: SpeakerBuilderComponent,
|
|
975
|
+
};
|
|
976
|
+
const DynamicComponents = {
|
|
977
|
+
[LessonComponentEnum.Speaker]: SpeakerComponent,
|
|
978
|
+
};
|
|
979
|
+
class DynamicComponentsService {
|
|
980
|
+
constructor() {
|
|
981
|
+
this._dynamicComponentBuilders = { ...DynamicComponentBuilders };
|
|
982
|
+
this._dynamicComponents = { ...DynamicComponents };
|
|
983
|
+
}
|
|
984
|
+
registerCustomComponent(component, name) {
|
|
985
|
+
// this._dynamicComponentBuilders[name || component.name] = component;
|
|
986
|
+
this._dynamicComponents[name || component.name] = component;
|
|
987
|
+
}
|
|
988
|
+
registerCustomComponentBuilder(component, name) {
|
|
989
|
+
this._dynamicComponentBuilders[name || component.name] = component;
|
|
990
|
+
}
|
|
991
|
+
getDynamicComponentBuilders(type) {
|
|
992
|
+
return this._dynamicComponentBuilders[type];
|
|
993
|
+
}
|
|
994
|
+
getDynamicComponentClass(type) {
|
|
995
|
+
return this._dynamicComponents[type];
|
|
996
|
+
}
|
|
997
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
998
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsService, providedIn: 'root' }); }
|
|
999
|
+
}
|
|
1000
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsService, decorators: [{
|
|
1001
|
+
type: Injectable,
|
|
1002
|
+
args: [{
|
|
1003
|
+
providedIn: 'root',
|
|
1004
|
+
}]
|
|
1005
|
+
}] });
|
|
1006
|
+
|
|
998
1007
|
class DCLessonRendererComponent {
|
|
999
1008
|
constructor() {
|
|
1000
1009
|
// --- Signal Inputs ---
|
|
1001
1010
|
this.lessonInput = input(); // Input signal for lesson object
|
|
1002
1011
|
this.lessonIdInput = input(); // Input signal for lesson ID
|
|
1003
|
-
this.
|
|
1012
|
+
this.settings = input();
|
|
1004
1013
|
// --- Outputs ---
|
|
1005
1014
|
this.wordClicked = new EventEmitter(); // New output event
|
|
1006
|
-
// ---
|
|
1015
|
+
// --- Services ---
|
|
1007
1016
|
this.renderer = inject(Renderer2);
|
|
1008
1017
|
this.viewContainerRef = inject(ViewContainerRef);
|
|
1009
1018
|
this.toastrService = inject(TOAST_ALERTS_TOKEN);
|
|
1010
1019
|
this.lessonService = inject(LESSONS_TOKEN);
|
|
1011
1020
|
this.lessonAIService = inject(LessonAIService); // Inject the new service
|
|
1012
1021
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
1013
|
-
|
|
1022
|
+
this.dynamicComponentsService = inject(DynamicComponentsService);
|
|
1014
1023
|
// --- State Signals ---
|
|
1015
1024
|
this.lesson = signal(undefined); // Internal lesson state signal
|
|
1016
1025
|
this.chatVisible = signal(false); // Signal for chat visibility
|
|
@@ -1018,6 +1027,7 @@ class DCLessonRendererComponent {
|
|
|
1018
1027
|
this.evaluatorAgentCard = signal(undefined); // Signal for evaluator card
|
|
1019
1028
|
this.conversationSettings = signal(undefined);
|
|
1020
1029
|
this.evalAgentTask = signal(undefined); // Signal for evaluator card
|
|
1030
|
+
this.backgroundTasks = {};
|
|
1021
1031
|
// --- Computed Signals ---
|
|
1022
1032
|
this.imageCover = computed(() => this.lesson()?.media?.images?.find((img) => img.type === 'cover')?.url); // Computed signal for imageCover
|
|
1023
1033
|
// --- Properties ---
|
|
@@ -1080,6 +1090,11 @@ class DCLessonRendererComponent {
|
|
|
1080
1090
|
}
|
|
1081
1091
|
});
|
|
1082
1092
|
}
|
|
1093
|
+
ngOnInit() {
|
|
1094
|
+
this.backgroundTasks = {
|
|
1095
|
+
[ConversationEvents.OnUserMessage]: this.evalAgentTask(),
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1083
1098
|
// --- Rendering Logic ---
|
|
1084
1099
|
_clearLessonRendering() {
|
|
1085
1100
|
// Destroy previously created dynamic components
|
|
@@ -1095,7 +1110,6 @@ class DCLessonRendererComponent {
|
|
|
1095
1110
|
_renderLesson(lessonData) {
|
|
1096
1111
|
this._clearLessonRendering(); // Clear previous state first
|
|
1097
1112
|
console.log('Rendering lesson:', lessonData.id);
|
|
1098
|
-
// console.log('Image cover URL:', this.imageCover()); // Access computed signal
|
|
1099
1113
|
// 1) Parse textCoded, create components, and build HTML structure
|
|
1100
1114
|
const { htmlContent, components } = this._parseAndCreateComponents(lessonData);
|
|
1101
1115
|
this.components = components;
|
|
@@ -1109,7 +1123,6 @@ class DCLessonRendererComponent {
|
|
|
1109
1123
|
_parseAndCreateComponents(lessonData) {
|
|
1110
1124
|
const r1 = new RegExp('~(.+?)~', 'g');
|
|
1111
1125
|
let count = 0;
|
|
1112
|
-
//
|
|
1113
1126
|
const createdComponents = {};
|
|
1114
1127
|
const htmlContent = lessonData.textCoded.replace(r1, (_matching, jsonCoded) => {
|
|
1115
1128
|
const componentName = `dynamicComp${count}`;
|
|
@@ -1162,7 +1175,7 @@ class DCLessonRendererComponent {
|
|
|
1162
1175
|
lessonCodedConfig = { ...lessonCodedConfig, ...foundConfig };
|
|
1163
1176
|
}
|
|
1164
1177
|
}
|
|
1165
|
-
const LessonClass =
|
|
1178
|
+
const LessonClass = this.dynamicComponentsService.getDynamicComponentClass(lessonCodedConfig.component);
|
|
1166
1179
|
if (!LessonClass) {
|
|
1167
1180
|
console.error(`Component class not found for type: ${lessonCodedConfig.component}. JSON: ${json}`);
|
|
1168
1181
|
return null; // Return null if class doesn't exist
|
|
@@ -1222,12 +1235,6 @@ class DCLessonRendererComponent {
|
|
|
1222
1235
|
}
|
|
1223
1236
|
}
|
|
1224
1237
|
});
|
|
1225
|
-
if (this.test()) {
|
|
1226
|
-
// Access signal value
|
|
1227
|
-
console.log('Test mode: Evaluation skipped saving.');
|
|
1228
|
-
this.toastrService.info({ subtitle: `Test Results: ${rates.correct} correct, ${rates.incorrect} incorrect`, title: 'Test Mode' });
|
|
1229
|
-
return;
|
|
1230
|
-
}
|
|
1231
1238
|
const totalQuestions = rates.correct + rates.incorrect;
|
|
1232
1239
|
rates.score = totalQuestions > 0 ? rates.correct / totalQuestions : 0; // Avoid division by zero
|
|
1233
1240
|
const status = rates.score >= 0.7 ? 'passed' : 'failed'; // Use >= for threshold
|
|
@@ -1269,7 +1276,7 @@ class DCLessonRendererComponent {
|
|
|
1269
1276
|
console.log('Requesting agent cards from LessonAIService...');
|
|
1270
1277
|
try {
|
|
1271
1278
|
// Call the service to get the agent cards
|
|
1272
|
-
const conversationSettings = await this.lessonAIService.generateConversationSettingsForLesson(currentLesson);
|
|
1279
|
+
const conversationSettings = await this.lessonAIService.generateConversationSettingsForLesson(currentLesson, this.settings());
|
|
1273
1280
|
if (conversationSettings) {
|
|
1274
1281
|
this.conversationSettings.set(conversationSettings);
|
|
1275
1282
|
this.chatVisible.set(true);
|
|
@@ -1312,11 +1319,11 @@ class DCLessonRendererComponent {
|
|
|
1312
1319
|
}
|
|
1313
1320
|
}
|
|
1314
1321
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1315
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonRendererComponent, isStandalone: true, selector: "dc-lesson-renderer", inputs: { lessonInput: { classPropertyName: "lessonInput", publicName: "lessonInput", isSignal: true, isRequired: false, transformFunction: null }, lessonIdInput: { classPropertyName: "lessonIdInput", publicName: "lessonIdInput", isSignal: true, isRequired: false, transformFunction: null },
|
|
1322
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonRendererComponent, isStandalone: true, selector: "dc-lesson-renderer", inputs: { lessonInput: { classPropertyName: "lessonInput", publicName: "lessonInput", isSignal: true, isRequired: false, transformFunction: null }, lessonIdInput: { classPropertyName: "lessonIdInput", publicName: "lessonIdInput", isSignal: true, isRequired: false, transformFunction: null }, settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { wordClicked: "wordClicked" }, viewQueries: [{ propertyName: "dynamicLesson", first: true, predicate: ["dynamicLesson"], descendants: true, static: true }], ngImport: i0, template: "<div>\n <div #dynamicLesson class=\"targetclass\">\n <ng-template #target></ng-template>\n </div>\n</div>\n\n<br />\n<div style=\"display: flex; gap: 10px\">\n @if ((mainForm.controls | keyvalue)?.length) {\n <div>\n <p-button label=\"Calificar Lecci\u00F3n\" icon=\"pi pi-check-circle\" (click)=\"evaluateForms()\" [rounded]=\"true\"></p-button>\n </div>\n }\n\n <p-button icon=\"pi pi-verified\" [rounded]=\"true\" (click)=\"startAI()\" label=\"Repasar con IA\" />\n</div>\n<br /><br />\n\n@if(chatVisible()) {\n<p-drawer header=\"Conversation\" [visible]=\"chatVisible()\" (visibleChange)=\"onVisibleChange($event)\" position=\"bottom\" styleClass=\"app-bottom-overlay\">\n <dc-chat\n [backgroundTasks]=\"backgroundTasks\"\n [conversationSettings]=\"conversationSettings()\"\n (goalCompleted)=\"handleGoalCompleted($event)\"\n (sendMessage)=\"onChatMessage($event)\"></dc-chat>\n</p-drawer>\n}\n", styles: [".evaluate{float:right}\n"], dependencies: [{ kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCChatComponent, selector: "dc-chat", inputs: ["chatUserSettings", "conversationSettings", "agentCard", "backgroundTasks", "taskOnUserMessage", "taskOnAssistantMessage", "parseDict"], outputs: ["sendMessage", "goalCompleted"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i2$2.Drawer, selector: "p-drawer", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }] }); }
|
|
1316
1323
|
}
|
|
1317
1324
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonRendererComponent, decorators: [{
|
|
1318
1325
|
type: Component,
|
|
1319
|
-
args: [{ selector: 'dc-lesson-renderer', standalone: true, imports: [KeyValuePipe, ButtonModule, DCChatComponent, DrawerModule], template: "<div>\n <div #dynamicLesson class=\"targetclass\">\n <ng-template #target></ng-template>\n </div>\n</div>\n\n<br />\n<div style=\"display: flex; gap: 10px\">\n @if ((mainForm.controls | keyvalue)?.length) {\n <div>\n <p-button label=\"Calificar Lecci\u00F3n\" icon=\"pi pi-check-circle\" (click)=\"evaluateForms()\" [rounded]=\"true\"></p-button>\n </div>\n }\n\n <p-button icon=\"pi pi-verified\" [rounded]=\"true\" (click)=\"startAI()\" label=\"Repasar con IA\" />\n</div>\n<br /><br />\n\n@if(chatVisible()) {\n<p-drawer header=\"Conversation\" [visible]=\"chatVisible()\" (visibleChange)=\"onVisibleChange($event)\" position=\"bottom\" styleClass=\"app-bottom-overlay\">\n <dc-chat\n [
|
|
1326
|
+
args: [{ selector: 'dc-lesson-renderer', standalone: true, imports: [KeyValuePipe, ButtonModule, DCChatComponent, DrawerModule], template: "<div>\n <div #dynamicLesson class=\"targetclass\">\n <ng-template #target></ng-template>\n </div>\n</div>\n\n<br />\n<div style=\"display: flex; gap: 10px\">\n @if ((mainForm.controls | keyvalue)?.length) {\n <div>\n <p-button label=\"Calificar Lecci\u00F3n\" icon=\"pi pi-check-circle\" (click)=\"evaluateForms()\" [rounded]=\"true\"></p-button>\n </div>\n }\n\n <p-button icon=\"pi pi-verified\" [rounded]=\"true\" (click)=\"startAI()\" label=\"Repasar con IA\" />\n</div>\n<br /><br />\n\n@if(chatVisible()) {\n<p-drawer header=\"Conversation\" [visible]=\"chatVisible()\" (visibleChange)=\"onVisibleChange($event)\" position=\"bottom\" styleClass=\"app-bottom-overlay\">\n <dc-chat\n [backgroundTasks]=\"backgroundTasks\"\n [conversationSettings]=\"conversationSettings()\"\n (goalCompleted)=\"handleGoalCompleted($event)\"\n (sendMessage)=\"onChatMessage($event)\"></dc-chat>\n</p-drawer>\n}\n", styles: [".evaluate{float:right}\n"] }]
|
|
1320
1327
|
}], ctorParameters: () => [], propDecorators: { wordClicked: [{
|
|
1321
1328
|
type: Output
|
|
1322
1329
|
}], dynamicLesson: [{
|
|
@@ -1745,45 +1752,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1745
1752
|
}]
|
|
1746
1753
|
}] });
|
|
1747
1754
|
|
|
1755
|
+
class DynamicComponentsBuilderService {
|
|
1756
|
+
#dialogService = inject(DialogService);
|
|
1757
|
+
#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1758
|
+
#dynamicComponentsService = inject(DynamicComponentsService);
|
|
1759
|
+
openComponentBuilder(componentType, data = null) {
|
|
1760
|
+
const componentToBuild = this.#dynamicComponentsService.getDynamicComponentBuilders(componentType);
|
|
1761
|
+
if (!componentToBuild) {
|
|
1762
|
+
console.error(`No component builder found for type: ${componentType}`);
|
|
1763
|
+
this.#toastService.error({ title: 'Error', subtitle: `Componente desconocido: ${componentType}` });
|
|
1764
|
+
return undefined;
|
|
1765
|
+
}
|
|
1766
|
+
const dialogRef = this.#dialogService.open(componentToBuild, {
|
|
1767
|
+
inputValues: {
|
|
1768
|
+
// inputValues was removed in newer PrimeNG versions, use 'data'
|
|
1769
|
+
inputs: data.inputs,
|
|
1770
|
+
id: data.id,
|
|
1771
|
+
},
|
|
1772
|
+
width: '80vw',
|
|
1773
|
+
header: 'Agregar componente',
|
|
1774
|
+
closable: true,
|
|
1775
|
+
});
|
|
1776
|
+
return dialogRef;
|
|
1777
|
+
}
|
|
1778
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1779
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsBuilderService, providedIn: 'root' }); }
|
|
1780
|
+
}
|
|
1781
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicComponentsBuilderService, decorators: [{
|
|
1782
|
+
type: Injectable,
|
|
1783
|
+
args: [{
|
|
1784
|
+
providedIn: 'root',
|
|
1785
|
+
}]
|
|
1786
|
+
}] });
|
|
1787
|
+
|
|
1748
1788
|
class DCLessonComponentAdderComponent {
|
|
1749
1789
|
constructor() {
|
|
1750
1790
|
// Services
|
|
1751
|
-
this.#
|
|
1752
|
-
this.#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1791
|
+
this.#dynamicComponentsBuilderService = inject(DynamicComponentsBuilderService);
|
|
1753
1792
|
this.componentAdded = new EventEmitter(); // Changed Output name and type
|
|
1754
1793
|
// Expose enum to the template
|
|
1755
1794
|
this.lessonComponentEnum = LessonComponentEnum;
|
|
1756
1795
|
}
|
|
1757
1796
|
// Services
|
|
1758
|
-
#
|
|
1759
|
-
|
|
1760
|
-
// Moved logic from DCLessonEditorComponent
|
|
1797
|
+
#dynamicComponentsBuilderService;
|
|
1798
|
+
// Logic to open component builder, now utilizing DynamicComponentsBuilderService
|
|
1761
1799
|
openComponentBuilder(type) {
|
|
1762
|
-
const
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1800
|
+
const dialogRef = this.#dynamicComponentsBuilderService.openComponentBuilder(type);
|
|
1801
|
+
if (dialogRef) {
|
|
1802
|
+
// Handle the result and emit the new event
|
|
1803
|
+
dialogRef.onClose.subscribe((result) => {
|
|
1804
|
+
if (result) {
|
|
1805
|
+
console.log('Component builder closed:', result);
|
|
1806
|
+
this.componentAdded.emit(result); // Emit the result when dialog closes successfully
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
else {
|
|
1811
|
+
// Optional: Log if the dialog couldn't be opened, though the service already logs an error.
|
|
1812
|
+
console.warn(`Dialog could not be opened for type via component: ${type}`);
|
|
1767
1813
|
}
|
|
1768
|
-
const dialogRef = this.#dialogService.open(componentToBuild, {
|
|
1769
|
-
width: '80vw',
|
|
1770
|
-
header: 'Agregar componente',
|
|
1771
|
-
closable: true,
|
|
1772
|
-
});
|
|
1773
|
-
// Handle the result and emit the new event
|
|
1774
|
-
dialogRef.onClose.subscribe((result) => {
|
|
1775
|
-
if (result) {
|
|
1776
|
-
console.log('Component builder closed:', result);
|
|
1777
|
-
this.componentAdded.emit(result); // Emit the result when dialog closes successfully
|
|
1778
|
-
}
|
|
1779
|
-
});
|
|
1780
1814
|
}
|
|
1781
1815
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonComponentAdderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1782
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: DCLessonComponentAdderComponent, isStandalone: true, selector: "dc-lesson-component-adder", outputs: { componentAdded: "componentAdded" }, providers: [DialogService], ngImport: i0, template: "<span>Componentes: </span>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap\">\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Selector)\"\n pTooltip=\"Agrega un selector con multiples opciones\"\n tooltipPosition=\"bottom\">\n Selector\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Speaker)\"\n pTooltip=\"Para que una palabra o frase sea reproducible\"\n tooltipPosition=\"bottom\">\n Speaker\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TextWriter)\"\n pTooltip=\"Escribe una respuesta en un cuadro de texto\"\n tooltipPosition=\"bottom\">\n Text\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.VerbSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de un verbo\"\n tooltipPosition=\"bottom\">\n Verb\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.WordSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de una palabra\"\n tooltipPosition=\"bottom\">\n Palabra\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TranslationSwitcher)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Traducci\u00F3n\n </p-button>\n <!-- Add other buttons here if needed, following the same pattern -->\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type:
|
|
1816
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: DCLessonComponentAdderComponent, isStandalone: true, selector: "dc-lesson-component-adder", outputs: { componentAdded: "componentAdded" }, providers: [DialogService], ngImport: i0, template: "<span>Componentes: </span>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap\">\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Selector)\"\n pTooltip=\"Agrega un selector con multiples opciones\"\n tooltipPosition=\"bottom\">\n Selector\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Speaker)\"\n pTooltip=\"Para que una palabra o frase sea reproducible\"\n tooltipPosition=\"bottom\">\n Speaker\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TextWriter)\"\n pTooltip=\"Escribe una respuesta en un cuadro de texto\"\n tooltipPosition=\"bottom\">\n Text\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.VerbSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de un verbo\"\n tooltipPosition=\"bottom\">\n Verb\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.WordSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de una palabra\"\n tooltipPosition=\"bottom\">\n Palabra\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TranslationSwitcher)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Traducci\u00F3n\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.PlayWord)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Play Word\n </p-button>\n <!-- Add other buttons here if needed, following the same pattern -->\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] }); }
|
|
1783
1817
|
}
|
|
1784
1818
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonComponentAdderComponent, decorators: [{
|
|
1785
1819
|
type: Component,
|
|
1786
|
-
args: [{ selector: 'dc-lesson-component-adder', standalone: true, imports: [CommonModule, ButtonModule, TooltipModule], providers: [DialogService], template: "<span>Componentes: </span>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap\">\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Selector)\"\n pTooltip=\"Agrega un selector con multiples opciones\"\n tooltipPosition=\"bottom\">\n Selector\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Speaker)\"\n pTooltip=\"Para que una palabra o frase sea reproducible\"\n tooltipPosition=\"bottom\">\n Speaker\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TextWriter)\"\n pTooltip=\"Escribe una respuesta en un cuadro de texto\"\n tooltipPosition=\"bottom\">\n Text\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.VerbSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de un verbo\"\n tooltipPosition=\"bottom\">\n Verb\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.WordSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de una palabra\"\n tooltipPosition=\"bottom\">\n Palabra\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TranslationSwitcher)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Traducci\u00F3n\n </p-button>\n <!-- Add other buttons here if needed, following the same pattern -->\n</div>\n" }]
|
|
1820
|
+
args: [{ selector: 'dc-lesson-component-adder', standalone: true, imports: [CommonModule, ButtonModule, TooltipModule], providers: [DialogService], template: "<span>Componentes: </span>\n<div style=\"display: flex; gap: 10px; flex-wrap: wrap\">\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Selector)\"\n pTooltip=\"Agrega un selector con multiples opciones\"\n tooltipPosition=\"bottom\">\n Selector\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.Speaker)\"\n pTooltip=\"Para que una palabra o frase sea reproducible\"\n tooltipPosition=\"bottom\">\n Speaker\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TextWriter)\"\n pTooltip=\"Escribe una respuesta en un cuadro de texto\"\n tooltipPosition=\"bottom\">\n Text\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.VerbSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de un verbo\"\n tooltipPosition=\"bottom\">\n Verb\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.WordSummary)\"\n pTooltip=\"Muestra la informaci\u00F3n de una palabra\"\n tooltipPosition=\"bottom\">\n Palabra\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.TranslationSwitcher)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Traducci\u00F3n\n </p-button>\n <p-button\n severity=\"info\"\n (click)=\"openComponentBuilder(lessonComponentEnum.PlayWord)\"\n pTooltip=\"Muestra el texto pero al pica cambia de idioma\"\n tooltipPosition=\"bottom\">\n Play Word\n </p-button>\n <!-- Add other buttons here if needed, following the same pattern -->\n</div>\n" }]
|
|
1787
1821
|
}], propDecorators: { componentAdded: [{
|
|
1788
1822
|
type: Output
|
|
1789
1823
|
}] } });
|
|
@@ -1981,10 +2015,10 @@ class DCLessonMetadataEditorComponent {
|
|
|
1981
2015
|
}
|
|
1982
2016
|
}
|
|
1983
2017
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonMetadataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1984
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonMetadataEditorComponent, isStandalone: true, selector: "dc-lesson-metadata-editor", inputs: { lesson: "lesson", isLoadingLesson: "isLoadingLesson" }, outputs: { saveRequest: "saveRequest", importNotionRequest: "importNotionRequest", improveNotionRequest: "improveNotionRequest" }, ngImport: i0, template: "@if (lesson(); as currentLesson) {\n<div>\n <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 <!-- Use one-way binding and ngModelChange for signals -->\n <div>\n <input\n pInputText\n style=\"width: 100%\"\n [ngModel]=\"currentLesson.metadata?.title\"\n (ngModelChange)=\"onMetadataPropertyChange('title', $event)\"\n type=\"text\"\n placeholder=\"Agrega un t\u00EDtulo\" />\n </div>\n <div style=\"margin-top: 4px\">\n <p-inputgroup>\n <input\n pInputText\n style=\"width: 100%\"\n [ngModel]=\"currentLesson.metadata?.description\"\n (ngModelChange)=\"onMetadataPropertyChange('description', $event)\"\n type=\"text\"\n 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\n <div style=\"display: flex; align-items: center; margin-top: 10px\">\n <input\n pInputText\n style=\"flex: auto; margin-right: 5px\"\n [ngModel]=\"currentLesson.metadata?.prompt\"\n (ngModelChange)=\"onMetadataPropertyChange('prompt', $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 <div style=\"margin-top: 10px\">\n <label class=\"checkbox-container\" style=\"margin-right: 15px\">\n <input\n type=\"checkbox\"\n [ngModel]=\"currentLesson.metadata?.isPublished\"\n (ngModelChange)=\"onMetadataPropertyChange('isPublished', $event)\"\n title=\"Cuando termines la edici\u00F3n marca esta casilla\" />\n <span class=\"checkmark\"></span>\n Publicada\n </label>\n </div>\n\n <p-divider />\n\n <div style=\"display: flex; align-items: center; margin-top: 10px; gap: 10px\">\n <input\n pInputText\n [ngModel]=\"currentLesson.appExtension?.['level']\"\n (ngModelChange)=\"onAppExtensionPropChange('level', $event)\"\n type=\"number\"\n placeholder=\"Nivel\"\n style=\"width: 80px\" />\n\n <!-- Access signal values -->\n @if (currentLesson.appExtension) {\n <div>\n {{ currentLesson.appExtension?.['baseLang'] | flagEmoji }} -> {{ currentLesson.appExtension?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ currentLesson.appExtension?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ currentLesson.appExtension?.['targetLang'] | langDesc : 'es' }}\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n<!-- Optional: Show a loading state or placeholder if lesson is undefined -->\n<p>Cargando datos de la lecci\u00F3n...</p>\n}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type:
|
|
2018
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonMetadataEditorComponent, isStandalone: true, selector: "dc-lesson-metadata-editor", inputs: { lesson: "lesson", isLoadingLesson: "isLoadingLesson" }, outputs: { saveRequest: "saveRequest", importNotionRequest: "importNotionRequest", improveNotionRequest: "improveNotionRequest" }, ngImport: i0, template: "@if (lesson(); as currentLesson) {\n<div>\n <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 <!-- Use one-way binding and ngModelChange for signals -->\n <div>\n <input\n pInputText\n style=\"width: 100%\"\n [ngModel]=\"currentLesson.metadata?.title\"\n (ngModelChange)=\"onMetadataPropertyChange('title', $event)\"\n type=\"text\"\n placeholder=\"Agrega un t\u00EDtulo\" />\n </div>\n <div style=\"margin-top: 4px\">\n <p-inputgroup>\n <input\n pInputText\n style=\"width: 100%\"\n [ngModel]=\"currentLesson.metadata?.description\"\n (ngModelChange)=\"onMetadataPropertyChange('description', $event)\"\n type=\"text\"\n 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\n <div style=\"display: flex; align-items: center; margin-top: 10px\">\n <input\n pInputText\n style=\"flex: auto; margin-right: 5px\"\n [ngModel]=\"currentLesson.metadata?.prompt\"\n (ngModelChange)=\"onMetadataPropertyChange('prompt', $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 <div style=\"margin-top: 10px\">\n <label class=\"checkbox-container\" style=\"margin-right: 15px\">\n <input\n type=\"checkbox\"\n [ngModel]=\"currentLesson.metadata?.isPublished\"\n (ngModelChange)=\"onMetadataPropertyChange('isPublished', $event)\"\n title=\"Cuando termines la edici\u00F3n marca esta casilla\" />\n <span class=\"checkmark\"></span>\n Publicada\n </label>\n </div>\n\n <p-divider />\n\n <div style=\"display: flex; align-items: center; margin-top: 10px; gap: 10px\">\n <input\n pInputText\n [ngModel]=\"currentLesson.appExtension?.['level']\"\n (ngModelChange)=\"onAppExtensionPropChange('level', $event)\"\n type=\"number\"\n placeholder=\"Nivel\"\n style=\"width: 80px\" />\n\n <!-- Access signal values -->\n @if (currentLesson.appExtension) {\n <div>\n {{ currentLesson.appExtension?.['baseLang'] | flagEmoji }} -> {{ currentLesson.appExtension?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ currentLesson.appExtension?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ currentLesson.appExtension?.['targetLang'] | langDesc : 'es' }}\n </div>\n }\n </div>\n </div>\n</div>\n} @else {\n<!-- Optional: Show a loading state or placeholder if lesson is undefined -->\n<p>Cargando datos de la lecci\u00F3n...</p>\n}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "pipe", type: // Added TooltipModule
|
|
1985
2019
|
FlagLanguagePipe, name: "flagEmoji" }, { kind: "pipe", type: // Added Pipe
|
|
1986
2020
|
LangDescTranslationPipe, name: "langDesc" }, { kind: "ngmodule", type: // Added Pipe
|
|
1987
|
-
InputGroupModule }, { kind: "component", type: i5
|
|
2021
|
+
InputGroupModule }, { kind: "component", type: i5.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i6$1.Divider, selector: "p-divider", inputs: ["style", "styleClass", "layout", "type", "align"] }] }); }
|
|
1988
2022
|
}
|
|
1989
2023
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonMetadataEditorComponent, decorators: [{
|
|
1990
2024
|
type: Component,
|
|
@@ -2139,6 +2173,7 @@ class DCLessonEditorComponent {
|
|
|
2139
2173
|
this.promptService = inject(PromptService);
|
|
2140
2174
|
this.ngxVertexService = inject(NgxVertexService);
|
|
2141
2175
|
this.cdr = inject(ChangeDetectorRef);
|
|
2176
|
+
this.dynamicComponentsBuilderService = inject(DynamicComponentsBuilderService);
|
|
2142
2177
|
// Signals States
|
|
2143
2178
|
this.lessonId = toSignal(inject(ActivatedRoute).paramMap.pipe(map((params) => params.get('id'))));
|
|
2144
2179
|
this.lesson = signal(undefined); // Initialize as undefined
|
|
@@ -2266,6 +2301,7 @@ class DCLessonEditorComponent {
|
|
|
2266
2301
|
const savedLesson = await this.#lessonService.postLesson(lessonToSave);
|
|
2267
2302
|
const currentId = this.lessonId();
|
|
2268
2303
|
if (!currentId) {
|
|
2304
|
+
// No se como guardar los extras aunt
|
|
2269
2305
|
// It was a new lesson, now it has an ID. Navigate.
|
|
2270
2306
|
this.#toastService.success({ title: 'Se creó la lección', subtitle: 'Éxito' });
|
|
2271
2307
|
// The effect should automatically fetch the lesson again after navigation due to paramMap change.
|
|
@@ -2399,8 +2435,14 @@ class DCLessonEditorComponent {
|
|
|
2399
2435
|
console.log(this.prompts);
|
|
2400
2436
|
this.cdr.markForCheck();
|
|
2401
2437
|
}
|
|
2438
|
+
editComponent(comp) {
|
|
2439
|
+
console.log('Edit component:', comp);
|
|
2440
|
+
this.dynamicComponentsBuilderService.openComponentBuilder(comp.component, comp).onClose.subscribe((result) => {
|
|
2441
|
+
this.onComponentAdded(result);
|
|
2442
|
+
});
|
|
2443
|
+
}
|
|
2402
2444
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCLessonEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2403
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonEditorComponent, isStandalone: true, selector: "dc-lesson-editor", providers: [LessonNotionService], viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef }, { propertyName: "dhtml", first: true, predicate: ["dhtml"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"position: relative; margin-bottom: 20px\">\n <img class=\"header-cover\" [src]=\"coverImageUrl()\" alt=\"Lesson Cover Image\" />\n\n <dc-cropper-modal\n style=\"position: absolute; top: 10px; left: 20px\"\n [buttonLabel]=\"'Carga una portada'\"\n [imgStorageSettings]=\"coverStorageSettings\"\n (imageUploaded)=\"onImageUploaded($event)\"></dc-cropper-modal>\n\n <p-button\n (click)=\"generateBanner()\"\n class=\"generate-banner-btn\"\n icon=\"pi pi-sparkles\"\n severity=\"primary\"\n [rounded]=\"true\"\n [raised]=\"true\"\n pTooltip=\"Generar Banner AI\"\n tooltipPosition=\"left\"></p-button>\n\n <p-button class=\"prompt-visual\" icon=\"pi pi-info\" label=\"Ver Prompts\" [link]=\"true\" (click)=\"showPrompts()\" />\n</div>\n\n<br />\n\n<!-- Lesson Metadata Editor -->\n<dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [isLoadingLesson]=\"isLoadingLesson\"\n (saveRequest)=\"saveLesson()\"\n (importNotionRequest)=\"importFromNotion()\"\n (improveNotionRequest)=\"improveNotionWithAI()\">\n</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>ID: {{ comp.id }} - Tipo: {{ comp.component }}<button pButton icon=\"pi pi-info\" (click)=\"showComponentDetails(comp)\"></button></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]=\"lesson()?.textCoded\"\n (ngModelChange)=\"updateLessonProperty('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"lesson()\"
|
|
2445
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCLessonEditorComponent, isStandalone: true, selector: "dc-lesson-editor", providers: [LessonNotionService], viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef }, { propertyName: "dhtml", first: true, predicate: ["dhtml"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"position: relative; margin-bottom: 20px\">\n <img class=\"header-cover\" [src]=\"coverImageUrl()\" alt=\"Lesson Cover Image\" />\n\n <dc-cropper-modal\n style=\"position: absolute; top: 10px; left: 20px\"\n [buttonLabel]=\"'Carga una portada'\"\n [imgStorageSettings]=\"coverStorageSettings\"\n (imageUploaded)=\"onImageUploaded($event)\"></dc-cropper-modal>\n\n <p-button\n (click)=\"generateBanner()\"\n class=\"generate-banner-btn\"\n icon=\"pi pi-sparkles\"\n severity=\"primary\"\n [rounded]=\"true\"\n [raised]=\"true\"\n pTooltip=\"Generar Banner AI\"\n tooltipPosition=\"left\"></p-button>\n\n <p-button class=\"prompt-visual\" icon=\"pi pi-info\" label=\"Ver Prompts\" [link]=\"true\" (click)=\"showPrompts()\" />\n</div>\n\n<br />\n\n<!-- Lesson Metadata Editor -->\n<dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [isLoadingLesson]=\"isLoadingLesson\"\n (saveRequest)=\"saveLesson()\"\n (importNotionRequest)=\"importFromNotion()\"\n (improveNotionRequest)=\"improveNotionWithAI()\">\n</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]=\"lesson()?.textCoded\"\n (ngModelChange)=\"updateLessonProperty('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"lesson()\"></dc-lesson-renderer>\n </ng-template>\n</p-splitter>\n\n<div class=\"float-button\">\n <!-- Removed p-speeddial -->\n <p-button icon=\"pi pi-save\" (click)=\"saveLesson()\" 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}\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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: CKEditorModule }, { kind: "component", type: i3$2.CKEditorComponent, selector: "ckeditor", inputs: ["editor", "config", "data", "tagName", "watchdog", "editorWatchdogConfig", "disableTwoWayDataBinding", "disabled"], outputs: ["ready", "change", "blur", "focus", "error"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { 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.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: SplitterModule }, { kind: "component", type: i5$1.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "style", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DCLessonComponentAdderComponent, selector: "dc-lesson-component-adder", outputs: ["componentAdded"] }, { kind: "component", type: // Add the component adder here
|
|
2404
2446
|
DCLessonMetadataEditorComponent, selector: "dc-lesson-metadata-editor", inputs: ["lesson", "isLoadingLesson"], outputs: ["saveRequest", "importNotionRequest", "improveNotionRequest"] }, { kind: "ngmodule", type: // Add the metadata editor here
|
|
2405
2447
|
DialogModule }, { kind: "component", type: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }] }); }
|
|
2406
2448
|
}
|
|
@@ -2418,7 +2460,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2418
2460
|
DCLessonComponentAdderComponent, // Add the component adder here
|
|
2419
2461
|
DCLessonMetadataEditorComponent, // Add the metadata editor here
|
|
2420
2462
|
DialogModule,
|
|
2421
|
-
], providers: [LessonNotionService], template: "<div style=\"position: relative; margin-bottom: 20px\">\n <img class=\"header-cover\" [src]=\"coverImageUrl()\" alt=\"Lesson Cover Image\" />\n\n <dc-cropper-modal\n style=\"position: absolute; top: 10px; left: 20px\"\n [buttonLabel]=\"'Carga una portada'\"\n [imgStorageSettings]=\"coverStorageSettings\"\n (imageUploaded)=\"onImageUploaded($event)\"></dc-cropper-modal>\n\n <p-button\n (click)=\"generateBanner()\"\n class=\"generate-banner-btn\"\n icon=\"pi pi-sparkles\"\n severity=\"primary\"\n [rounded]=\"true\"\n [raised]=\"true\"\n pTooltip=\"Generar Banner AI\"\n tooltipPosition=\"left\"></p-button>\n\n <p-button class=\"prompt-visual\" icon=\"pi pi-info\" label=\"Ver Prompts\" [link]=\"true\" (click)=\"showPrompts()\" />\n</div>\n\n<br />\n\n<!-- Lesson Metadata Editor -->\n<dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [isLoadingLesson]=\"isLoadingLesson\"\n (saveRequest)=\"saveLesson()\"\n (importNotionRequest)=\"importFromNotion()\"\n (improveNotionRequest)=\"improveNotionWithAI()\">\n</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>ID: {{ comp.id }} - Tipo: {{ comp.component }}<button pButton icon=\"pi pi-info\" (click)=\"showComponentDetails(comp)\"></button></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]=\"lesson()?.textCoded\"\n (ngModelChange)=\"updateLessonProperty('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"lesson()\"
|
|
2463
|
+
], providers: [LessonNotionService], template: "<div style=\"position: relative; margin-bottom: 20px\">\n <img class=\"header-cover\" [src]=\"coverImageUrl()\" alt=\"Lesson Cover Image\" />\n\n <dc-cropper-modal\n style=\"position: absolute; top: 10px; left: 20px\"\n [buttonLabel]=\"'Carga una portada'\"\n [imgStorageSettings]=\"coverStorageSettings\"\n (imageUploaded)=\"onImageUploaded($event)\"></dc-cropper-modal>\n\n <p-button\n (click)=\"generateBanner()\"\n class=\"generate-banner-btn\"\n icon=\"pi pi-sparkles\"\n severity=\"primary\"\n [rounded]=\"true\"\n [raised]=\"true\"\n pTooltip=\"Generar Banner AI\"\n tooltipPosition=\"left\"></p-button>\n\n <p-button class=\"prompt-visual\" icon=\"pi pi-info\" label=\"Ver Prompts\" [link]=\"true\" (click)=\"showPrompts()\" />\n</div>\n\n<br />\n\n<!-- Lesson Metadata Editor -->\n<dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [isLoadingLesson]=\"isLoadingLesson\"\n (saveRequest)=\"saveLesson()\"\n (importNotionRequest)=\"importFromNotion()\"\n (improveNotionRequest)=\"improveNotionWithAI()\">\n</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]=\"lesson()?.textCoded\"\n (ngModelChange)=\"updateLessonProperty('textCoded', $event)\">\n </ckeditor>\n </ng-template>\n\n <ng-template pTemplate>\n <dc-lesson-renderer class=\"text-editor\" [lessonInput]=\"lesson()\"></dc-lesson-renderer>\n </ng-template>\n</p-splitter>\n\n<div class=\"float-button\">\n <!-- Removed p-speeddial -->\n <p-button icon=\"pi pi-save\" (click)=\"saveLesson()\" 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}\n"] }]
|
|
2422
2464
|
}], ctorParameters: () => [], propDecorators: { target: [{
|
|
2423
2465
|
type: ViewChild,
|
|
2424
2466
|
args: ['target', { read: ViewContainerRef }]
|
|
@@ -2446,6 +2488,283 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2446
2488
|
type: Input
|
|
2447
2489
|
}] } });
|
|
2448
2490
|
|
|
2491
|
+
const Endpoints$1 = {
|
|
2492
|
+
courses: 'api/courses',
|
|
2493
|
+
};
|
|
2494
|
+
class CoursesService {
|
|
2495
|
+
constructor() {
|
|
2496
|
+
this.httpCoreService = inject(HttpCoreService);
|
|
2497
|
+
}
|
|
2498
|
+
// Not sure how to implement this yet.
|
|
2499
|
+
getCourses() {
|
|
2500
|
+
return this.httpCoreService.get(Endpoints$1.courses);
|
|
2501
|
+
}
|
|
2502
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2503
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesService, providedIn: 'root' }); }
|
|
2504
|
+
}
|
|
2505
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesService, decorators: [{
|
|
2506
|
+
type: Injectable,
|
|
2507
|
+
args: [{
|
|
2508
|
+
providedIn: 'root',
|
|
2509
|
+
}]
|
|
2510
|
+
}] });
|
|
2511
|
+
|
|
2512
|
+
class CoursesAdminComponent {
|
|
2513
|
+
constructor() {
|
|
2514
|
+
this.httpCoreService = inject(HttpCoreService);
|
|
2515
|
+
}
|
|
2516
|
+
async ngOnInit() {
|
|
2517
|
+
const courses = await this.httpCoreService.get('courses');
|
|
2518
|
+
console.log(courses);
|
|
2519
|
+
}
|
|
2520
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesAdminComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2521
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: CoursesAdminComponent, isStandalone: true, selector: "ngx-courses-admin", ngImport: i0, template: "<p>welcome to courses creation</p>\n", styles: [""] }); }
|
|
2522
|
+
}
|
|
2523
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesAdminComponent, decorators: [{
|
|
2524
|
+
type: Component,
|
|
2525
|
+
args: [{ selector: 'ngx-courses-admin', standalone: true, template: "<p>welcome to courses creation</p>\n" }]
|
|
2526
|
+
}] });
|
|
2527
|
+
|
|
2528
|
+
class CoursesComponent {
|
|
2529
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2530
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: CoursesComponent, isStandalone: true, selector: "app-courses", ngImport: i0, template: "<router-outlet />\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2531
|
+
}
|
|
2532
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CoursesComponent, decorators: [{
|
|
2533
|
+
type: Component,
|
|
2534
|
+
args: [{ selector: 'app-courses', imports: [RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<router-outlet />\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
2535
|
+
}] });
|
|
2536
|
+
|
|
2537
|
+
class CourseDetailComponent {
|
|
2538
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2539
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: CourseDetailComponent, isStandalone: true, selector: "app-course-detail", ngImport: i0, template: `<p>course-detail works!</p>`, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2540
|
+
}
|
|
2541
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseDetailComponent, decorators: [{
|
|
2542
|
+
type: Component,
|
|
2543
|
+
args: [{ selector: 'app-course-detail', imports: [], template: `<p>course-detail works!</p>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
|
|
2544
|
+
}] });
|
|
2545
|
+
|
|
2546
|
+
const server = 'primary';
|
|
2547
|
+
// TODO add your own end points
|
|
2548
|
+
const Endpoints = {
|
|
2549
|
+
Courses: {
|
|
2550
|
+
Courses: 'api/courses',
|
|
2551
|
+
CoursesFiltered: 'api/courses/query',
|
|
2552
|
+
},
|
|
2553
|
+
};
|
|
2554
|
+
class CourseService {
|
|
2555
|
+
constructor() {
|
|
2556
|
+
this.httpService = inject(HttpCoreService);
|
|
2557
|
+
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2558
|
+
}
|
|
2559
|
+
async getCourses() {
|
|
2560
|
+
try {
|
|
2561
|
+
const response = await this.httpService.get(Endpoints.Courses.Courses, server);
|
|
2562
|
+
this.toastService.success({ title: 'Se han encontrado generics', subtitle: 'Mostrando información' });
|
|
2563
|
+
return response;
|
|
2564
|
+
}
|
|
2565
|
+
catch (error) {
|
|
2566
|
+
this.toastService.warn({ title: 'Error fetching generics', subtitle: 'Showing Default Data' });
|
|
2567
|
+
// return RemoveSimpleDataExample;
|
|
2568
|
+
return [];
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
async getFilteredCourses(filter) {
|
|
2572
|
+
return this.httpService.post(Endpoints.Courses.CoursesFiltered, filter, server);
|
|
2573
|
+
}
|
|
2574
|
+
async getCourse(id) {
|
|
2575
|
+
return this.httpService.get(`${Endpoints.Courses.Courses}/${id}`);
|
|
2576
|
+
}
|
|
2577
|
+
async saveCourse(course) {
|
|
2578
|
+
return this.httpService.post(Endpoints.Courses.Courses, course);
|
|
2579
|
+
}
|
|
2580
|
+
async deleteCourse(id) {
|
|
2581
|
+
return this.httpService.delete(`${Endpoints.Courses.Courses}/${id}`);
|
|
2582
|
+
}
|
|
2583
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2584
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseService, providedIn: 'root' }); }
|
|
2585
|
+
}
|
|
2586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseService, decorators: [{
|
|
2587
|
+
type: Injectable,
|
|
2588
|
+
args: [{
|
|
2589
|
+
providedIn: 'root',
|
|
2590
|
+
}]
|
|
2591
|
+
}] });
|
|
2592
|
+
|
|
2593
|
+
class CourseListComponent extends PaginationBase {
|
|
2594
|
+
constructor() {
|
|
2595
|
+
super(...arguments);
|
|
2596
|
+
// Services
|
|
2597
|
+
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2598
|
+
this.sourceService = inject(CourseService);
|
|
2599
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
2600
|
+
// Inputs
|
|
2601
|
+
this.viewType = 'card';
|
|
2602
|
+
this.onlyView = input(true);
|
|
2603
|
+
this.onSelect = output();
|
|
2604
|
+
// States
|
|
2605
|
+
this.courses = signal([]);
|
|
2606
|
+
this.columns = ['name', 'description', 'updatedAt', 'image'];
|
|
2607
|
+
this.filterBarOptions = { showActions: true, showCreateButton: true, showViewButton: true };
|
|
2608
|
+
}
|
|
2609
|
+
getCustomButtons(item) {
|
|
2610
|
+
return [
|
|
2611
|
+
{
|
|
2612
|
+
tooltipOptions: { tooltipLabel: 'Ver detalles', tooltipPosition: 'bottom' },
|
|
2613
|
+
icon: 'pi pi-eye',
|
|
2614
|
+
command: () => this.doAction({ item, action: 'view' }),
|
|
2615
|
+
},
|
|
2616
|
+
{
|
|
2617
|
+
label: 'Editar',
|
|
2618
|
+
icon: 'pi pi-pencil',
|
|
2619
|
+
command: () => this.doAction({ item, action: 'edit' }),
|
|
2620
|
+
},
|
|
2621
|
+
{
|
|
2622
|
+
label: 'Eliminar',
|
|
2623
|
+
icon: 'pi pi-trash',
|
|
2624
|
+
command: () => this.doAction({ item, action: 'delete' }),
|
|
2625
|
+
},
|
|
2626
|
+
];
|
|
2627
|
+
}
|
|
2628
|
+
async ngOnInit() {
|
|
2629
|
+
this.filterConfig.returnProps = { _id: 1, id: 1, name: 1, description: 1, updatedAt: 1, image: 1 };
|
|
2630
|
+
const response = await this.sourceService.getFilteredCourses(this.filterConfig);
|
|
2631
|
+
this.courses.set(response.rows);
|
|
2632
|
+
this.cdr.detectChanges();
|
|
2633
|
+
console.log(this.courses(), this.viewType);
|
|
2634
|
+
this.cdr.detectChanges();
|
|
2635
|
+
}
|
|
2636
|
+
loadData() {
|
|
2637
|
+
throw new Error('Method not implemented.');
|
|
2638
|
+
}
|
|
2639
|
+
onNew() {
|
|
2640
|
+
console.log('onNew');
|
|
2641
|
+
this.router.navigate(['./edit'], { relativeTo: this.route });
|
|
2642
|
+
}
|
|
2643
|
+
toggleView() {
|
|
2644
|
+
this.viewType = this.viewType === 'card' ? 'table' : 'card';
|
|
2645
|
+
console.log(this.viewType, this.courses());
|
|
2646
|
+
this.cdr.detectChanges();
|
|
2647
|
+
}
|
|
2648
|
+
selectItem(course) {
|
|
2649
|
+
console.log('onSelect');
|
|
2650
|
+
this.onSelect.emit(course);
|
|
2651
|
+
}
|
|
2652
|
+
async doAction(actionEvent) {
|
|
2653
|
+
const { item, action } = actionEvent;
|
|
2654
|
+
if (action == 'changeView') {
|
|
2655
|
+
this.toggleView();
|
|
2656
|
+
}
|
|
2657
|
+
switch (action) {
|
|
2658
|
+
case 'view':
|
|
2659
|
+
this.router.navigate(['./details', item.id], { relativeTo: this.route });
|
|
2660
|
+
break;
|
|
2661
|
+
case 'delete':
|
|
2662
|
+
const areYouSure = confirm('¿Estás seguro de querer eliminar este origen?');
|
|
2663
|
+
if (areYouSure) {
|
|
2664
|
+
const id = item.id || item._id;
|
|
2665
|
+
await this.sourceService.deleteCourse(id);
|
|
2666
|
+
this.courses.set(this.courses().filter((course) => course._id !== id));
|
|
2667
|
+
this.toastService.success({
|
|
2668
|
+
title: 'Origen eliminado',
|
|
2669
|
+
subtitle: 'El origen ha sido eliminado correctamente',
|
|
2670
|
+
});
|
|
2671
|
+
this.cdr.detectChanges();
|
|
2672
|
+
}
|
|
2673
|
+
break;
|
|
2674
|
+
case 'edit':
|
|
2675
|
+
this.router.navigate(['./edit', item.id], { relativeTo: this.route });
|
|
2676
|
+
break;
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2680
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: CourseListComponent, isStandalone: true, selector: "app-course-list", inputs: { viewType: { classPropertyName: "viewType", publicName: "viewType", isSignal: false, isRequired: false, transformFunction: null }, onlyView: { classPropertyName: "onlyView", publicName: "onlyView", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelect: "onSelect" }, usesInheritance: true, ngImport: i0, template: "@if (!onlyView()) {\n<p-button [icon]=\"viewType === 'card' ? 'pi pi-table' : 'pi pi-list'\" label=\"Change View\" [link]=\"true\" (click)=\"toggleView()\" />\n}\n<div class=\"course-list-container\">\n <dc-filter-bar [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType === 'card') {\n <div class=\"course-list-content\">\n @for (course of courses(); track course.id) {\n <div class=\"card-source\">\n <div style=\"position: absolute; top: 4px; right: 4px; z-index: 1000\">\n <p-speeddial\n [model]=\"getCustomButtons(course)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card [header]=\"course.name\">\n <p class=\"m-0\">{{ course.description | slice : 0 : 250 }}...</p>\n <span>{{ course.updatedAt | date : 'dd/MM/yyyy HH:mm' }}</span>\n </p-card>\n </div>\n } @if (courses().length === 0) {\n <p-card>\n <p>No courses found</p>\n </p-card>\n }\n </div>\n } @else if ( viewType == 'table'){\n\n <app-quick-table [tableData]=\"courses()\"></app-quick-table>\n\n }\n\n <div class=\"paginator-container\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.course-list-container{display:flex;flex-direction:column;height:100%}.course-list-content{margin-top:10px;flex:1;overflow-y:auto;padding-bottom:10px}.card-source{margin-bottom:10px;position:relative}.paginator-container{margin-top:auto;padding-top:10px}\n"], dependencies: [{ kind: "ngmodule", type: CardModule }, { kind: "component", type: i3$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters"], outputs: ["onFilterAction", "onChangeSort", "onNew"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$1.SpeedDial, selector: "p-speeddial, p-speedDial, p-speed-dial", inputs: ["id", "model", "visible", "style", "className", "direction", "transitionDelay", "type", "radius", "mask", "disabled", "hideOnClickOutside", "buttonStyle", "buttonClassName", "maskStyle", "maskClassName", "showIcon", "hideIcon", "rotateAnimation", "ariaLabel", "ariaLabelledBy", "tooltipOptions", "buttonProps"], outputs: ["onVisibleChange", "visibleChange", "onClick", "onShow", "onHide"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SlicePipe, name: "slice" }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$2.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2681
|
+
}
|
|
2682
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseListComponent, decorators: [{
|
|
2683
|
+
type: Component,
|
|
2684
|
+
args: [{ selector: 'app-course-list', imports: [
|
|
2685
|
+
CardModule,
|
|
2686
|
+
ButtonModule,
|
|
2687
|
+
DCFilterBarComponent,
|
|
2688
|
+
SpeedDialModule,
|
|
2689
|
+
DatePipe,
|
|
2690
|
+
SlicePipe,
|
|
2691
|
+
PaginatorModule,
|
|
2692
|
+
RouterModule,
|
|
2693
|
+
TableModule,
|
|
2694
|
+
QuickTableComponent,
|
|
2695
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!onlyView()) {\n<p-button [icon]=\"viewType === 'card' ? 'pi pi-table' : 'pi pi-list'\" label=\"Change View\" [link]=\"true\" (click)=\"toggleView()\" />\n}\n<div class=\"course-list-container\">\n <dc-filter-bar [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType === 'card') {\n <div class=\"course-list-content\">\n @for (course of courses(); track course.id) {\n <div class=\"card-source\">\n <div style=\"position: absolute; top: 4px; right: 4px; z-index: 1000\">\n <p-speeddial\n [model]=\"getCustomButtons(course)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card [header]=\"course.name\">\n <p class=\"m-0\">{{ course.description | slice : 0 : 250 }}...</p>\n <span>{{ course.updatedAt | date : 'dd/MM/yyyy HH:mm' }}</span>\n </p-card>\n </div>\n } @if (courses().length === 0) {\n <p-card>\n <p>No courses found</p>\n </p-card>\n }\n </div>\n } @else if ( viewType == 'table'){\n\n <app-quick-table [tableData]=\"courses()\"></app-quick-table>\n\n }\n\n <div class=\"paginator-container\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.course-list-container{display:flex;flex-direction:column;height:100%}.course-list-content{margin-top:10px;flex:1;overflow-y:auto;padding-bottom:10px}.card-source{margin-bottom:10px;position:relative}.paginator-container{margin-top:auto;padding-top:10px}\n"] }]
|
|
2696
|
+
}], propDecorators: { viewType: [{
|
|
2697
|
+
type: Input
|
|
2698
|
+
}] } });
|
|
2699
|
+
|
|
2700
|
+
class CourseFormComponent {
|
|
2701
|
+
constructor() {
|
|
2702
|
+
this.route = inject(ActivatedRoute);
|
|
2703
|
+
this.courseService = inject(CourseService);
|
|
2704
|
+
this.fb = inject(FormBuilder);
|
|
2705
|
+
this.router = inject(Router);
|
|
2706
|
+
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2707
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
2708
|
+
this.storageImgSettings = {
|
|
2709
|
+
path: `courses`,
|
|
2710
|
+
cropSettings: { aspectRatio: AspectType.Square, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 700 },
|
|
2711
|
+
};
|
|
2712
|
+
this.extraFields = [
|
|
2713
|
+
{ key: 'title', type: 'input', props: { label: 'Title', placeholder: 'Title', required: false } },
|
|
2714
|
+
{ key: 'content', type: 'textarea', props: { label: 'Content', placeholder: 'Content', required: false } },
|
|
2715
|
+
];
|
|
2716
|
+
this.courseForm = this.fb.group({
|
|
2717
|
+
name: ['', Validators.required],
|
|
2718
|
+
description: [''],
|
|
2719
|
+
image: [{}],
|
|
2720
|
+
});
|
|
2721
|
+
this.course = null;
|
|
2722
|
+
this.courseId = this.route.snapshot.params['id'];
|
|
2723
|
+
}
|
|
2724
|
+
async ngOnInit() {
|
|
2725
|
+
if (this.courseId) {
|
|
2726
|
+
this.course = await this.courseService.getCourse(this.courseId);
|
|
2727
|
+
if (this.course) {
|
|
2728
|
+
this.courseForm.patchValue(this.course);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
async save() {
|
|
2733
|
+
if (this.courseForm.valid) {
|
|
2734
|
+
const course = { ...this.course, ...this.courseForm.value };
|
|
2735
|
+
const result = await this.courseService.saveCourse(course);
|
|
2736
|
+
if (!this.courseId) {
|
|
2737
|
+
this.router.navigate([result.id], { relativeTo: this.route });
|
|
2738
|
+
}
|
|
2739
|
+
this.toastService.success({ title: 'Origen guardado', subtitle: 'El origen ha sido guardado correctamente' });
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
handleImageUpload(event) {
|
|
2743
|
+
// this.genericForm.patchValue({ image: event });
|
|
2744
|
+
alert('Image uploaded');
|
|
2745
|
+
}
|
|
2746
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2747
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: CourseFormComponent, isStandalone: true, selector: "app-source-form", ngImport: i0, template: "<h3>Courses Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"courseId ? 'Edit Course' : 'New Course'\">\n <form [formGroup]=\"courseForm\">\n <div style=\"display: flex; gap: 10px\">\n <div class=\"form-field\">\n <label class=\"block\" pTooltip=\"Image should be handle after upload\">Subir imagen</label>\n <img width=\"218px\" src=\"assets/images/face-3.jpg\" />\n <dc-cropper-modal [imgStorageSettings]=\"storageImgSettings\" (imageUploaded)=\"handleImageUpload($event)\"></dc-cropper-modal>\n </div>\n\n <div style=\"width: 100%\">\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Name</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter source name\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\" class=\"block\">Description</label>\n <textarea id=\"description\" pTextarea formControlName=\"description\" rows=\"5\" class=\"w-full\" placeholder=\"Enter source content\"> </textarea>\n </div>\n </div>\n </div>\n </form>\n\n <div style=\"display: flex; justify-content: flex-end\">\n <p-button (click)=\"save()\" label=\"Save Course\" [disabled]=\"!courseForm.valid\" icon=\"pi pi-check\" iconPos=\"right\"> </p-button>\n </div>\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { 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: CardModule }, { kind: "component", type: i3$1.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: DropdownModule }, { 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", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "ngmodule", type: FormlyModule }, { kind: "ngmodule", type: DialogModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2748
|
+
}
|
|
2749
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: CourseFormComponent, decorators: [{
|
|
2750
|
+
type: Component,
|
|
2751
|
+
args: [{ selector: 'app-source-form', imports: [
|
|
2752
|
+
ReactiveFormsModule,
|
|
2753
|
+
CardModule,
|
|
2754
|
+
TextareaModule,
|
|
2755
|
+
DropdownModule,
|
|
2756
|
+
ButtonModule,
|
|
2757
|
+
SelectModule,
|
|
2758
|
+
InputTextModule,
|
|
2759
|
+
ChipModule,
|
|
2760
|
+
TooltipModule,
|
|
2761
|
+
CropperComponentModal,
|
|
2762
|
+
FormlyModule,
|
|
2763
|
+
DialogModule,
|
|
2764
|
+
CourseListComponent,
|
|
2765
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<h3>Courses Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"courseId ? 'Edit Course' : 'New Course'\">\n <form [formGroup]=\"courseForm\">\n <div style=\"display: flex; gap: 10px\">\n <div class=\"form-field\">\n <label class=\"block\" pTooltip=\"Image should be handle after upload\">Subir imagen</label>\n <img width=\"218px\" src=\"assets/images/face-3.jpg\" />\n <dc-cropper-modal [imgStorageSettings]=\"storageImgSettings\" (imageUploaded)=\"handleImageUpload($event)\"></dc-cropper-modal>\n </div>\n\n <div style=\"width: 100%\">\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Name</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter source name\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\" class=\"block\">Description</label>\n <textarea id=\"description\" pTextarea formControlName=\"description\" rows=\"5\" class=\"w-full\" placeholder=\"Enter source content\"> </textarea>\n </div>\n </div>\n </div>\n </form>\n\n <div style=\"display: flex; justify-content: flex-end\">\n <p-button (click)=\"save()\" label=\"Save Course\" [disabled]=\"!courseForm.valid\" icon=\"pi pi-check\" iconPos=\"right\"> </p-button>\n </div>\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"] }]
|
|
2766
|
+
}] });
|
|
2767
|
+
|
|
2449
2768
|
/*
|
|
2450
2769
|
* Public API Surface of lessons
|
|
2451
2770
|
*/
|
|
@@ -2454,5 +2773,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2454
2773
|
* Generated bundle index. Do not edit.
|
|
2455
2774
|
*/
|
|
2456
2775
|
|
|
2457
|
-
export { ComponentBuilder, ComponentWithForm, DCLessonEditorComponent, DCLessonFormComponent, DCLessonListComponent, DCLessonRendererComponent, DcLessonCardComponent, DefaultLessonsService, FlagLanguagePipe, LESSONS_TOKEN, LangCodeDescription, LangCodeDescriptionEs, LangDescTranslationPipe, LessonComponentBuilders, LessonComponentEnum, LessonComponents, LessonDynamicComponent, LessonsAbstractService, NOTION_SERVICE_TOKEN, NotionAbstractService, NotionExportType, SelectorBuilderComponent, SelectorComponent, TextWriterBuiderComponent, TextWriterComponent, TranslationSwitcherBuilderComponent, TranslationSwitcherComponent, getLanguageSimpleAgent, getLessonComponentClass, provideLessonsService, provideNotionService };
|
|
2776
|
+
export { ComponentBuilder, ComponentWithForm, CourseDetailComponent, CourseFormComponent, CourseListComponent, CourseService, CoursesAdminComponent, CoursesComponent, CoursesService, DCLessonEditorComponent, DCLessonFormComponent, DCLessonListComponent, DCLessonRendererComponent, DcLessonCardComponent, DefaultLessonsService, DynamicComponentBuilders, DynamicComponents, DynamicComponentsService, FlagLanguagePipe, LESSONS_TOKEN, LangCodeDescription, LangCodeDescriptionEs, LangDescTranslationPipe, LessonComponentBuilders, LessonComponentEnum, LessonComponents, LessonDynamicComponent, LessonsAbstractService, NOTION_SERVICE_TOKEN, NotionAbstractService, NotionExportType, SelectorBuilderComponent, SelectorComponent, TextWriterBuiderComponent, TextWriterComponent, TranslationSwitcherBuilderComponent, TranslationSwitcherComponent, getLanguageSimpleAgent, getLessonComponentClass, provideLessonsService, provideNotionService };
|
|
2458
2777
|
//# sourceMappingURL=dataclouder-ngx-lessons.mjs.map
|