@dataclouder/ngx-lessons 0.1.3 → 0.1.4
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 +543 -537
- package/fesm2022/dataclouder-ngx-lessons.mjs.map +1 -1
- package/index.d.ts +643 -5
- package/package.json +1 -1
- package/lib/components/courses/course-detail/course-detail.component.d.ts +0 -5
- package/lib/components/courses/course-form/course-form.component.d.ts +0 -35
- package/lib/components/courses/course-list/course-list.component.d.ts +0 -25
- package/lib/components/courses/courses.component.d.ts +0 -5
- package/lib/components/courses/courses.service.d.ts +0 -14
- package/lib/components/courses/models/courses.model.d.ts +0 -24
- package/lib/components/courses-admin/courses-admin.component.d.ts +0 -8
- package/lib/components/dc-lessons/dc-lesson-card/dc-lesson-card.component.d.ts +0 -25
- package/lib/components/dc-lessons/dc-lesson-component-adder/dc-lesson-component-adder.component.d.ts +0 -11
- package/lib/components/dc-lessons/dc-lesson-editor/dc-lesson-editor.component.d.ts +0 -67
- package/lib/components/dc-lessons/dc-lesson-metadata-editor/dc-lesson-metadata-editor.component.d.ts +0 -43
- package/lib/components/dc-lessons/dc-lesson-renderer/dc-lesson-renderer.component.d.ts +0 -51
- package/lib/components/dc-lessons/dc-lesson-renderer/eval-agents-skills.d.ts +0 -1
- package/lib/components/dc-lessons/lesson-form/lesson-form.component.d.ts +0 -5
- package/lib/components/dc-lessons/lesson-list/dc-lesson-list.component.d.ts +0 -36
- package/lib/components/dynamic-components/dynamic-components-builder.service.d.ts +0 -8
- package/lib/components/dynamic-components/dynamic-components.service.d.ts +0 -30
- package/lib/components/dynamic-components/selector/selector-builder/selector-builder.component.d.ts +0 -16
- package/lib/components/dynamic-components/selector/selector.component.d.ts +0 -12
- package/lib/components/lesson-mini-components/components/ComponentBuilder.d.ts +0 -33
- package/lib/components/lesson-mini-components/components/ComponentWithForm.d.ts +0 -12
- package/lib/components/lesson-mini-components/components/lesson-dynamic.component.d.ts +0 -7
- package/lib/components/lesson-mini-components/components/lessons.clases.d.ts +0 -159
- package/lib/components/lesson-mini-components/components/speaker/speaker-builder/speaker-builder.component.d.ts +0 -14
- package/lib/components/lesson-mini-components/components/speaker/speaker.component.d.ts +0 -12
- package/lib/components/lesson-mini-components/components/text-writer/text-writer-buider/text-writer-buider.component.d.ts +0 -7
- package/lib/components/lesson-mini-components/components/text-writer/text-writer.component.d.ts +0 -16
- package/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcher.component.d.ts +0 -11
- package/lib/components/lesson-mini-components/components/translationSwitcher/translationSwitcherBuilder/translationSwitcherBuilder.component.d.ts +0 -7
- package/lib/models/lessons.pipes.d.ts +0 -28
- package/lib/models/notion.models.d.ts +0 -41
- package/lib/models/simple-agents.d.ts +0 -2
- package/lib/services/courses.service.d.ts +0 -7
- package/lib/services/default-lessons.service.d.ts +0 -20
- package/lib/services/lesson-ai.service.d.ts +0 -32
- package/lib/services/lesson-notion.service.d.ts +0 -35
- package/lib/services/lesson-utils.service.d.ts +0 -56
- package/public-api.d.ts +0 -27
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Pipe, InjectionToken, inject, Input, Component, ChangeDetectionStrategy, signal, EventEmitter, Output,
|
|
3
|
-
import * as i1$2 from 'primeng/paginator';
|
|
4
|
-
import { PaginatorModule } from 'primeng/paginator';
|
|
2
|
+
import { Pipe, InjectionToken, inject, Input, Component, ChangeDetectionStrategy, signal, EventEmitter, Output, Injectable, effect, ViewChildren, input, Renderer2, ViewContainerRef, computed, ViewChild, ChangeDetectorRef, output } from '@angular/core';
|
|
5
3
|
import { DatePipe, NgComponentOutlet, KeyValuePipe, CommonModule, SlicePipe } from '@angular/common';
|
|
6
4
|
import * as i1$3 from '@angular/router';
|
|
7
5
|
import { RouterModule, ActivatedRoute, Router } from '@angular/router';
|
|
8
|
-
import {
|
|
6
|
+
import { EntityCommunicationService, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent, TOAST_ALERTS_TOKEN, UiStateService, EModelQuality, LoadingBarService, PromptService, DcExtensionsViewerComponent, DcLearnableViewerComponent, DcAuditableViewerComponent, DcManageableViewerComponent, DcReactionsViewerComponent, HttpCoreService, PaginationBase, EntityBaseFormComponent, getSupportedLanguageOptions } from '@dataclouder/ngx-core';
|
|
9
7
|
import * as i1 from '@angular/forms';
|
|
10
8
|
import { FormBuilder, FormControl, FormArray, FormsModule, ReactiveFormsModule, UntypedFormControl, FormGroup, Validators } from '@angular/forms';
|
|
11
9
|
import * as i1$1 from 'primeng/button';
|
|
@@ -14,12 +12,11 @@ import * as i3 from 'primeng/inputtext';
|
|
|
14
12
|
import { InputTextModule } from 'primeng/inputtext';
|
|
15
13
|
import { DynamicDialogRef, DialogService } from 'primeng/dynamicdialog';
|
|
16
14
|
import { nanoid } from 'nanoid';
|
|
17
|
-
import { DropdownModule } from 'primeng/dropdown';
|
|
18
|
-
import { NgxTtsComponent, getRandomQuickVoice } from '@dataclouder/ngx-tts';
|
|
19
|
-
import * as i4 from 'primeng/message';
|
|
20
|
-
import { MessageModule } from 'primeng/message';
|
|
21
15
|
import * as i2 from 'primeng/select';
|
|
22
16
|
import { SelectModule } from 'primeng/select';
|
|
17
|
+
import { TTSPlayground, getRandomQuickVoice, NgxVertexService, ChatRoleVertex } from '@dataclouder/ngx-vertex';
|
|
18
|
+
import * as i4 from 'primeng/message';
|
|
19
|
+
import { MessageModule } from 'primeng/message';
|
|
23
20
|
import { PopoverModule } from 'primeng/popover';
|
|
24
21
|
import * as i4$1 from 'primeng/tag';
|
|
25
22
|
import { TagModule } from 'primeng/tag';
|
|
@@ -27,6 +24,8 @@ import * as i2$1 from 'primeng/speeddial';
|
|
|
27
24
|
import { SpeedDialModule } from 'primeng/speeddial';
|
|
28
25
|
import * as i3$1 from 'primeng/card';
|
|
29
26
|
import { CardModule } from 'primeng/card';
|
|
27
|
+
import * as i1$2 from 'primeng/paginator';
|
|
28
|
+
import { PaginatorModule } from 'primeng/paginator';
|
|
30
29
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
31
30
|
import { map } from 'rxjs';
|
|
32
31
|
import BalloonEditor from '@ckeditor/ckeditor5-build-balloon-block';
|
|
@@ -34,10 +33,10 @@ import * as i3$2 from '@ckeditor/ckeditor5-angular';
|
|
|
34
33
|
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
|
|
35
34
|
import * as i5$1 from 'primeng/splitter';
|
|
36
35
|
import { SplitterModule } from 'primeng/splitter';
|
|
37
|
-
import * as
|
|
36
|
+
import * as i2$3 from 'primeng/tooltip';
|
|
38
37
|
import { TooltipModule } from 'primeng/tooltip';
|
|
39
|
-
import { ResolutionType, AspectType, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
|
|
40
|
-
import { TextEngines, ConversationType, USER_DATA_EXCHANGE, ChatRole, EvalResultStringDefinition, ConversationEvents, ChatEventType, DCChatComponent, CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
38
|
+
import { ResolutionType, AspectType, AssetsLoaderComponent, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
|
|
39
|
+
import { TextEngines, ConversationType, USER_DATA_EXCHANGE, SystemPromptType, ChatRole, EvalResultStringDefinition, EDoActionType, ConditionOperator, ConditionType, ConversationEvents, ChatEventType, DCChatComponent, CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
41
40
|
import * as i2$2 from 'primeng/drawer';
|
|
42
41
|
import { DrawerModule } from 'primeng/drawer';
|
|
43
42
|
import * as i7 from 'primeng/dialog';
|
|
@@ -46,17 +45,15 @@ import TurndownService from 'turndown';
|
|
|
46
45
|
import { marked } from 'marked';
|
|
47
46
|
import * as i5 from 'primeng/inputgroup';
|
|
48
47
|
import { InputGroupModule } from 'primeng/inputgroup';
|
|
49
|
-
import * as i6
|
|
48
|
+
import * as i6 from 'primeng/divider';
|
|
50
49
|
import { DividerModule } from 'primeng/divider';
|
|
51
|
-
import
|
|
52
|
-
import
|
|
50
|
+
import * as i2$4 from 'primeng/api';
|
|
51
|
+
import { TableModule } from 'primeng/table';
|
|
53
52
|
import * as i3$3 from 'primeng/textarea';
|
|
54
53
|
import { TextareaModule } from 'primeng/textarea';
|
|
55
54
|
import { ChipModule } from 'primeng/chip';
|
|
56
55
|
import { FormlyModule } from '@ngx-formly/core';
|
|
57
|
-
import { TableModule } from 'primeng/table';
|
|
58
56
|
|
|
59
|
-
// import { LangCodeDescription, LangCodeDescriptionEs } from '../components/lesson-mini-components/components/lessons.clases';
|
|
60
57
|
// This pipe should not be here in the lessons, refactor when is posible and remove LangCodeDescription
|
|
61
58
|
const LangCodeDescription = {
|
|
62
59
|
es: 'Spanish',
|
|
@@ -83,10 +80,10 @@ class LangDescTranslationPipe {
|
|
|
83
80
|
return LangCodeDescription[value];
|
|
84
81
|
}
|
|
85
82
|
}
|
|
86
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
87
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "
|
|
83
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LangDescTranslationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
84
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: LangDescTranslationPipe, isStandalone: true, name: "langDesc" }); }
|
|
88
85
|
}
|
|
89
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
86
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LangDescTranslationPipe, decorators: [{
|
|
90
87
|
type: Pipe,
|
|
91
88
|
args: [{
|
|
92
89
|
name: 'langDesc',
|
|
@@ -114,10 +111,10 @@ class FlagLanguagePipe {
|
|
|
114
111
|
return '';
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
118
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "
|
|
114
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: FlagLanguagePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
115
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: FlagLanguagePipe, isStandalone: true, name: "flagEmoji" }); }
|
|
119
116
|
}
|
|
120
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
117
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: FlagLanguagePipe, decorators: [{
|
|
121
118
|
type: Pipe,
|
|
122
119
|
args: [{
|
|
123
120
|
name: 'flagEmoji',
|
|
@@ -289,10 +286,10 @@ class ComponentBuilder {
|
|
|
289
286
|
await navigator.clipboard.writeText(data.str);
|
|
290
287
|
this.ref.close(data);
|
|
291
288
|
}
|
|
292
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
293
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
289
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ComponentBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
290
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: ComponentBuilder, isStandalone: true, selector: "app-component-builder", inputs: { inputs: "inputs", id: "id" }, ngImport: i0, template: '<div>no template</div>', isInline: true }); }
|
|
294
291
|
}
|
|
295
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
292
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ComponentBuilder, decorators: [{
|
|
296
293
|
type: Component,
|
|
297
294
|
args: [{
|
|
298
295
|
selector: 'app-component-builder',
|
|
@@ -309,10 +306,10 @@ class TextWriterBuiderComponent extends ComponentBuilder {
|
|
|
309
306
|
super(...arguments);
|
|
310
307
|
this.componentName = 'TextWriter';
|
|
311
308
|
}
|
|
312
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
313
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
309
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TextWriterBuiderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
310
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }] }); }
|
|
314
311
|
}
|
|
315
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
312
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TextWriterBuiderComponent, decorators: [{
|
|
316
313
|
type: Component,
|
|
317
314
|
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
315
|
}] });
|
|
@@ -330,10 +327,10 @@ class ComponentWithForm {
|
|
|
330
327
|
validate() {
|
|
331
328
|
// TODO: generic method to evaluate
|
|
332
329
|
}
|
|
333
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
334
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
330
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ComponentWithForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
331
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: ComponentWithForm, isStandalone: true, selector: "app-component-form", ngImport: i0, template: '<div>no template</div>', isInline: true }); }
|
|
335
332
|
}
|
|
336
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ComponentWithForm, decorators: [{
|
|
337
334
|
type: Component,
|
|
338
335
|
args: [{
|
|
339
336
|
selector: 'app-component-form',
|
|
@@ -376,10 +373,10 @@ class TextWriterComponent extends ComponentWithForm {
|
|
|
376
373
|
}
|
|
377
374
|
return true;
|
|
378
375
|
}
|
|
379
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
380
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
376
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TextWriterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
377
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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: ["pSize", "variant", "fluid", "invalid"] }] }); }
|
|
381
378
|
}
|
|
382
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
379
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TextWriterComponent, decorators: [{
|
|
383
380
|
type: Component,
|
|
384
381
|
args: [{ selector: 'app-text-writer', standalone: true, imports: [FormsModule, ReactiveFormsModule, InputTextModule], 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"] }]
|
|
385
382
|
}], ctorParameters: () => [], propDecorators: { config: [{
|
|
@@ -391,10 +388,10 @@ class TranslationSwitcherBuilderComponent extends ComponentBuilder {
|
|
|
391
388
|
super(...arguments);
|
|
392
389
|
this.componentName = 'TranslationSwitcher';
|
|
393
390
|
}
|
|
394
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
395
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
391
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TranslationSwitcherBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
392
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
396
393
|
}
|
|
397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
394
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TranslationSwitcherBuilderComponent, decorators: [{
|
|
398
395
|
type: Component,
|
|
399
396
|
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"] }]
|
|
400
397
|
}] });
|
|
@@ -415,10 +412,10 @@ class TranslationSwitcherComponent {
|
|
|
415
412
|
this.visibleText = this.config.settings.text;
|
|
416
413
|
}
|
|
417
414
|
}
|
|
418
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
419
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
415
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TranslationSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
416
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: TranslationSwitcherComponent, isStandalone: true, selector: "app-translation-switcher", inputs: { config: "config" }, ngImport: i0, template: "<button\n pButton\n style=\"padding: 0px 2px\"\n severity=\"help\"\n size=\"small\"\n (click)=\"switchTranslation()\"\n [label]=\"visibleText\"\n [text]=\"true\"\n [rounded]=\"true\"></button>\n", styles: [":host{display:block}\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"] }], changeDetection: i0.ChangeDetectionStrategy.Default }); }
|
|
420
417
|
}
|
|
421
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
418
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: TranslationSwitcherComponent, decorators: [{
|
|
422
419
|
type: Component,
|
|
423
420
|
args: [{ selector: 'app-translation-switcher', standalone: true, imports: [ButtonModule], changeDetection: ChangeDetectionStrategy.Default, template: "<button\n pButton\n style=\"padding: 0px 2px\"\n severity=\"help\"\n size=\"small\"\n (click)=\"switchTranslation()\"\n [label]=\"visibleText\"\n [text]=\"true\"\n [rounded]=\"true\"></button>\n", styles: [":host{display:block}\n"] }]
|
|
424
421
|
}], propDecorators: { config: [{
|
|
@@ -429,7 +426,7 @@ class SpeakerBuilderComponent extends ComponentBuilder {
|
|
|
429
426
|
constructor() {
|
|
430
427
|
super(...arguments);
|
|
431
428
|
this.componentName = 'Speaker';
|
|
432
|
-
this.tts = signal(undefined);
|
|
429
|
+
this.tts = signal(undefined, ...(ngDevMode ? [{ debugName: "tts" }] : []));
|
|
433
430
|
}
|
|
434
431
|
handleTtsGenerated(event) {
|
|
435
432
|
console.log('TTS generated:', event);
|
|
@@ -450,16 +447,15 @@ class SpeakerBuilderComponent extends ComponentBuilder {
|
|
|
450
447
|
};
|
|
451
448
|
return code;
|
|
452
449
|
}
|
|
453
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
454
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
450
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SpeakerBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
451
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: SpeakerBuilderComponent, isStandalone: true, selector: "app-speaker-builder", usesInheritance: true, ngImport: i0, template: "<div>\r\n <div>\r\n <h5>Constructor de Speaker</h5>\r\n </div>\r\n\r\n <tts-playground (ttsGenerated)=\"handleTtsGenerated($event)\"></tts-playground>\r\n\r\n <br />\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"!tts()\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: TTSPlayground, selector: "tts-playground", inputs: ["path"], outputs: ["ttsGenerated"] }] }); }
|
|
455
452
|
}
|
|
456
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
453
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SpeakerBuilderComponent, decorators: [{
|
|
457
454
|
type: Component,
|
|
458
|
-
args: [{ selector: 'app-speaker-builder', standalone: true, imports: [FormsModule, ReactiveFormsModule, InputTextModule, ButtonModule,
|
|
455
|
+
args: [{ selector: 'app-speaker-builder', standalone: true, imports: [FormsModule, ReactiveFormsModule, InputTextModule, ButtonModule, SelectModule, TTSPlayground], template: "<div>\r\n <div>\r\n <h5>Constructor de Speaker</h5>\r\n </div>\r\n\r\n <tts-playground (ttsGenerated)=\"handleTtsGenerated($event)\"></tts-playground>\r\n\r\n <br />\r\n <div>\r\n <p-button (click)=\"copyToClipboard()\" [disabled]=\"formGroup.invalid\" label=\"Copia C\u00F3digo\" [rounded]=\"true\"></p-button>\r\n <p-button (click)=\"showCode()\" [disabled]=\"!tts()\" label=\"Mostrar\" [rounded]=\"true\" severity=\"secondary\"></p-button>\r\n </div>\r\n</div>\r\n" }]
|
|
459
456
|
}] });
|
|
460
457
|
|
|
461
458
|
// ❌ can use this until i copy services to this lib
|
|
462
|
-
// import { CONVERSATION_AI_TOKEN } from '@dataclouder/ngx-agent-cards';
|
|
463
459
|
class SpeakerComponent {
|
|
464
460
|
ngOnInit() {
|
|
465
461
|
// throw new Error('Method not implemented.');
|
|
@@ -469,16 +465,11 @@ class SpeakerComponent {
|
|
|
469
465
|
// ngOnInit(): void {}
|
|
470
466
|
speach() {
|
|
471
467
|
console.log('should speech but will do in next version');
|
|
472
|
-
// if (this.config.audio) {
|
|
473
|
-
// this.audioService.playAudio(this.config.audio.url);
|
|
474
|
-
// } else {
|
|
475
|
-
// this.speachService.speach(this.config.settings.text);
|
|
476
|
-
// }
|
|
477
468
|
}
|
|
478
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
479
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
469
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SpeakerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
470
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: SpeakerComponent, isStandalone: true, selector: "app-speaker", inputs: { config: "config", tts: "tts" }, ngImport: i0, template: "<button\r\n pButton\r\n style=\"padding: 0px 2px\"\r\n severity=\"help\"\r\n size=\"small\"\r\n (click)=\"speach()\"\r\n [label]=\"config?.settings?.text\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"></button>\r\n", styles: [".lisen{cursor:pointer}\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"] }] }); }
|
|
480
471
|
}
|
|
481
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
472
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SpeakerComponent, decorators: [{
|
|
482
473
|
type: Component,
|
|
483
474
|
args: [{ selector: 'app-speaker', standalone: true, imports: [ButtonModule], template: "<button\r\n pButton\r\n style=\"padding: 0px 2px\"\r\n severity=\"help\"\r\n size=\"small\"\r\n (click)=\"speach()\"\r\n [label]=\"config?.settings?.text\"\r\n [text]=\"true\"\r\n [rounded]=\"true\"></button>\r\n", styles: [".lisen{cursor:pointer}\n"] }]
|
|
484
475
|
}], propDecorators: { config: [{
|
|
@@ -515,10 +506,10 @@ class SelectorComponent extends ComponentWithForm {
|
|
|
515
506
|
}
|
|
516
507
|
return true;
|
|
517
508
|
}
|
|
518
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
519
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
509
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
510
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
|
|
520
511
|
}
|
|
521
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SelectorComponent, decorators: [{
|
|
522
513
|
type: Component,
|
|
523
514
|
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
515
|
}], ctorParameters: () => [], propDecorators: { config: [{
|
|
@@ -563,10 +554,10 @@ class SelectorBuilderComponent extends ComponentBuilder {
|
|
|
563
554
|
get optionsForm() {
|
|
564
555
|
return this.formGroup.get('options');
|
|
565
556
|
}
|
|
566
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
567
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
557
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SelectorBuilderComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
558
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: 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
559
|
}
|
|
569
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
560
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: SelectorBuilderComponent, decorators: [{
|
|
570
561
|
type: Component,
|
|
571
562
|
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
563
|
}] });
|
|
@@ -603,8 +594,19 @@ function getLessonComponentClass(type) {
|
|
|
603
594
|
return LessonComponents[type];
|
|
604
595
|
}
|
|
605
596
|
const LESSONS_TOKEN = new InjectionToken('Lessons Service');
|
|
606
|
-
class LessonsAbstractService {
|
|
607
|
-
|
|
597
|
+
// export abstract class LessonsAbstractService extends EntityCommunicationService<ILesson> {
|
|
598
|
+
// abstract getLessons(paginator?: any): Promise<any>;
|
|
599
|
+
// abstract getLesson(id: string): Promise<any>;
|
|
600
|
+
// abstract postLesson(lesson: ILesson): Promise<any>;
|
|
601
|
+
// abstract updateLesson(lesson: ILesson): Promise<any>;
|
|
602
|
+
// abstract deleteLesson(id: string): Promise<any>;
|
|
603
|
+
// abstract generateLesson(lesson: ILesson): Promise<any>;
|
|
604
|
+
// abstract postGenerateByAI(id: string): Promise<any>;
|
|
605
|
+
// abstract extractTextFromHtml(html: string): string;
|
|
606
|
+
// abstract postImproveMDWithAI(lessonId: string, markdownText: string): Promise<any>; // Added for AI Markdown improvement
|
|
607
|
+
// abstract saveTakenLesson(lesson: ILessonTaken): Promise<any>;
|
|
608
|
+
// abstract getPrompts(): LessonPrompts;
|
|
609
|
+
// }
|
|
608
610
|
// my-service.provider.ts
|
|
609
611
|
function provideLessonsService(serviceImplementation) {
|
|
610
612
|
return [
|
|
@@ -621,6 +623,7 @@ var EventCard;
|
|
|
621
623
|
EventCard["Delete"] = "delete";
|
|
622
624
|
EventCard["Select"] = "select";
|
|
623
625
|
EventCard["Qr"] = "qr";
|
|
626
|
+
EventCard["Clone"] = "clone";
|
|
624
627
|
})(EventCard || (EventCard = {}));
|
|
625
628
|
class DcLessonCardComponent {
|
|
626
629
|
constructor() {
|
|
@@ -630,27 +633,9 @@ class DcLessonCardComponent {
|
|
|
630
633
|
this.coverUrl = 'assets/background/default-background.webp';
|
|
631
634
|
this.eventType = EventCard;
|
|
632
635
|
this.items = [
|
|
633
|
-
{
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
command: () => {
|
|
637
|
-
this.eventCard(EventCard.Edit);
|
|
638
|
-
},
|
|
639
|
-
},
|
|
640
|
-
{
|
|
641
|
-
label: 'Eliminar',
|
|
642
|
-
icon: 'pi pi-trash',
|
|
643
|
-
command: () => {
|
|
644
|
-
this.eventCard(EventCard.Delete);
|
|
645
|
-
},
|
|
646
|
-
},
|
|
647
|
-
{
|
|
648
|
-
label: 'Tomar lección',
|
|
649
|
-
icon: 'pi pi-play',
|
|
650
|
-
command: () => {
|
|
651
|
-
this.eventCard(EventCard.Select);
|
|
652
|
-
},
|
|
653
|
-
},
|
|
636
|
+
{ label: 'Clonar', icon: 'pi pi-copy', command: () => this.eventCard(EventCard.Clone) },
|
|
637
|
+
{ label: 'Editar', icon: 'pi pi-pencil', command: () => this.eventCard(EventCard.Edit) },
|
|
638
|
+
{ label: 'Eliminar', icon: 'pi pi-trash', command: () => this.eventCard(EventCard.Delete) },
|
|
654
639
|
];
|
|
655
640
|
}
|
|
656
641
|
ngOnInit() {
|
|
@@ -658,27 +643,14 @@ class DcLessonCardComponent {
|
|
|
658
643
|
this.lesson?.banner?.url || this.lesson?.metadata?.banner?.url || this.lesson?.media?.images?.[0]?.url || 'assets/background/default-background.webp';
|
|
659
644
|
}
|
|
660
645
|
eventCard(eventType) {
|
|
661
|
-
|
|
662
|
-
case EventCard.Edit:
|
|
663
|
-
this.onAction.emit({ action: 'edit', item: this.lesson });
|
|
664
|
-
break;
|
|
665
|
-
case EventCard.Delete:
|
|
666
|
-
this.onAction.emit({ action: 'delete', item: this.lesson });
|
|
667
|
-
break;
|
|
668
|
-
case EventCard.Select:
|
|
669
|
-
this.onAction.emit({ action: 'select', item: this.lesson });
|
|
670
|
-
break;
|
|
671
|
-
case EventCard.Qr:
|
|
672
|
-
this.onAction.emit({ action: 'qr', item: this.lesson });
|
|
673
|
-
break;
|
|
674
|
-
}
|
|
646
|
+
this.onAction.emit({ action: eventType, item: this.lesson });
|
|
675
647
|
}
|
|
676
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
677
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
648
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcLessonCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
649
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 [tooltipOptions]=\"{ tooltipPosition: 'top' }\" />\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: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: 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: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: DatePipe, name: "date" }] }); }
|
|
678
650
|
}
|
|
679
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
651
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcLessonCardComponent, decorators: [{
|
|
680
652
|
type: Component,
|
|
681
|
-
args: [{ selector: 'dc-lesson-card', standalone: true, imports: [DatePipe, ButtonModule, PopoverModule, SpeedDialModule, CardModule, TagModule], 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"] }]
|
|
653
|
+
args: [{ selector: 'dc-lesson-card', standalone: true, imports: [DatePipe, ButtonModule, PopoverModule, SpeedDialModule, CardModule, TagModule], 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 [tooltipOptions]=\"{ tooltipPosition: 'top' }\" />\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"] }]
|
|
682
654
|
}], propDecorators: { lesson: [{
|
|
683
655
|
type: Input
|
|
684
656
|
}], showOptions: [{
|
|
@@ -689,141 +661,209 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
689
661
|
type: Output
|
|
690
662
|
}] } });
|
|
691
663
|
|
|
664
|
+
class DefaultLessonsService extends EntityCommunicationService {
|
|
665
|
+
constructor() {
|
|
666
|
+
super('lesson');
|
|
667
|
+
// --- Endpoint Definitions for methods not in EntityCommunicationService ---
|
|
668
|
+
this.endpoints = {
|
|
669
|
+
saveTakenLesson: `api/user/saveLesson`,
|
|
670
|
+
generateLesson: `api/lesson/generate`,
|
|
671
|
+
generateByAI: `api/lesson/generate-ai`,
|
|
672
|
+
improveMDWithAI: `api/lesson/improve-markdown-ai`,
|
|
673
|
+
GenerateBanner: 'api/lesson/generate-banner',
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
// --- Method Implementations from LessonsAbstractService ---
|
|
677
|
+
async getLessons(filters = {}) {
|
|
678
|
+
if (!filters.returnProps) {
|
|
679
|
+
filters.returnProps = {
|
|
680
|
+
level: 1,
|
|
681
|
+
title: 1,
|
|
682
|
+
description: 1,
|
|
683
|
+
createdDate: 1,
|
|
684
|
+
banner: 1,
|
|
685
|
+
metadata: 1,
|
|
686
|
+
appExtensions: 1,
|
|
687
|
+
media: 1,
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
return this.query(filters);
|
|
691
|
+
}
|
|
692
|
+
async getLesson(id) {
|
|
693
|
+
return this.findOne(id);
|
|
694
|
+
}
|
|
695
|
+
async postLesson(lesson) {
|
|
696
|
+
return this.createOrUpdate(lesson);
|
|
697
|
+
}
|
|
698
|
+
async updateLesson(lesson) {
|
|
699
|
+
if (!lesson._id) {
|
|
700
|
+
throw new Error('Lesson ID is required for update.');
|
|
701
|
+
}
|
|
702
|
+
return this.createOrUpdate(lesson);
|
|
703
|
+
}
|
|
704
|
+
async deleteLesson(id) {
|
|
705
|
+
await this.remove(id);
|
|
706
|
+
}
|
|
707
|
+
// --- Methods specific to lessons ---
|
|
708
|
+
saveTakenLesson(lesson) {
|
|
709
|
+
return this.httpService.post(this.endpoints.saveTakenLesson, lesson);
|
|
710
|
+
}
|
|
711
|
+
async generateLesson(lesson) {
|
|
712
|
+
return this.httpService.post(this.endpoints.generateLesson, lesson);
|
|
713
|
+
}
|
|
714
|
+
async postGenerateByAI(id) {
|
|
715
|
+
return this.httpService.post(this.endpoints.generateByAI, { id });
|
|
716
|
+
}
|
|
717
|
+
async postImproveMDWithAI(lessonId, markdownText) {
|
|
718
|
+
return this.httpService.post(this.endpoints.improveMDWithAI, { id: lessonId, markdown: markdownText });
|
|
719
|
+
}
|
|
720
|
+
generateBanner(prompt, lessonId) {
|
|
721
|
+
return this.httpService.post(this.endpoints.GenerateBanner, { prompt, lessonId });
|
|
722
|
+
}
|
|
723
|
+
extractTextFromHtml(html) {
|
|
724
|
+
const r1 = new RegExp('~(.+?)~', 'g');
|
|
725
|
+
const lessonHtml = html.replace(r1, (_matching, jsonCoded) => {
|
|
726
|
+
try {
|
|
727
|
+
const data = JSON.parse(jsonCoded);
|
|
728
|
+
return `<span>${data?.settings?.text || ''}</span>`;
|
|
729
|
+
}
|
|
730
|
+
catch (e) {
|
|
731
|
+
console.error('Error parsing JSON in extractTextFromHtml:', jsonCoded, e);
|
|
732
|
+
return '';
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
let text = lessonHtml.replace(/<[^>]*>/g, ' ');
|
|
736
|
+
text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, ' ');
|
|
737
|
+
text = text.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, ' ');
|
|
738
|
+
text = text.replace(/ /g, ' ');
|
|
739
|
+
text = text.replace(/&/g, '&');
|
|
740
|
+
text = text.replace(/</g, '<');
|
|
741
|
+
text = text.replace(/>/g, '>');
|
|
742
|
+
text = text.replace(/\s+/g, ' ').trim();
|
|
743
|
+
return text;
|
|
744
|
+
}
|
|
745
|
+
getPrompts() {
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DefaultLessonsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
749
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DefaultLessonsService, providedIn: 'root' }); }
|
|
750
|
+
}
|
|
751
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DefaultLessonsService, decorators: [{
|
|
752
|
+
type: Injectable,
|
|
753
|
+
args: [{
|
|
754
|
+
providedIn: 'root',
|
|
755
|
+
}]
|
|
756
|
+
}], ctorParameters: () => [] });
|
|
757
|
+
|
|
692
758
|
const tableViewColumns = [
|
|
693
759
|
{ field: 'media.images[0].url', header: 'Image', type: 'image' },
|
|
694
760
|
{ field: 'title', header: 'Título' },
|
|
695
761
|
{ field: 'description', header: 'Descripción' },
|
|
696
762
|
];
|
|
697
|
-
|
|
698
|
-
{ title: 'select', label: 'Select', icon: 'pi pi-check', severity: 'primary' },
|
|
699
|
-
{ title: 'qr', label: 'QR', icon: 'pi pi-qrcode', severity: 'info' },
|
|
700
|
-
{ title: 'edit', label: 'Edit', icon: 'pi pi-pencil', severity: 'info' },
|
|
701
|
-
{ title: 'delete', label: 'Delete', icon: 'pi pi-trash', severity: 'danger' },
|
|
702
|
-
];
|
|
703
|
-
const returnProperties = { id: 1, title: 1, assets: 1 };
|
|
704
|
-
class DCLessonListComponent extends PaginationBase {
|
|
763
|
+
class DCLessonListComponent extends EntityBaseListComponent {
|
|
705
764
|
constructor() {
|
|
706
|
-
super(
|
|
707
|
-
this.showOptions = true;
|
|
765
|
+
super();
|
|
708
766
|
this.customFilters = [];
|
|
709
|
-
this.viewType = 'cards';
|
|
710
767
|
// Injected Services
|
|
711
|
-
|
|
712
|
-
this.
|
|
713
|
-
this.toastrService = inject(TOAST_ALERTS_TOKEN);
|
|
768
|
+
// I dont rename so use the same in EntityBaseListComponent and Pagination
|
|
769
|
+
this.entityCommunicationService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
714
770
|
this.columns = tableViewColumns;
|
|
715
|
-
|
|
771
|
+
// Private properties
|
|
716
772
|
this.cardEventSubs = [];
|
|
717
|
-
this.
|
|
718
|
-
|
|
773
|
+
this.filterConfig.returnProps = {
|
|
774
|
+
title: 1,
|
|
775
|
+
description: 1,
|
|
776
|
+
media: 1,
|
|
777
|
+
_id: 1,
|
|
778
|
+
id: 1,
|
|
779
|
+
};
|
|
780
|
+
effect(() => {
|
|
781
|
+
// When items signal changes, re-subscribe to card events
|
|
782
|
+
this.items(); // a little hack to make the effect run when items change
|
|
783
|
+
setTimeout(() => this.subscribeToCardEvents());
|
|
784
|
+
});
|
|
719
785
|
}
|
|
720
|
-
ngOnInit() {
|
|
721
|
-
this.filterConfig.returnProps = returnProperties;
|
|
786
|
+
async ngOnInit() {
|
|
722
787
|
this.cardComponent = this.customCardComponent || DcLessonCardComponent;
|
|
723
|
-
|
|
724
|
-
this.filterBarOptions = { showCreateButton: this.showOptions, showViewButton: this.showOptions, showActions: this.showOptions };
|
|
725
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
726
|
-
}
|
|
727
|
-
subscribeDinamicInstantToEvents() {
|
|
728
|
-
this.clearcardEventSubs();
|
|
729
|
-
this.subscribeToCardEvents();
|
|
730
|
-
}
|
|
731
|
-
subscribeToCardEvents() {
|
|
732
|
-
this.outlets.forEach((outlet) => {
|
|
733
|
-
const instance = outlet.componentInstance;
|
|
734
|
-
this.cardEventSubs.push(instance.onAction.subscribe((lesson) => {
|
|
735
|
-
this.doOrEmitAction(lesson);
|
|
736
|
-
}));
|
|
737
|
-
});
|
|
788
|
+
await super.ngOnInit();
|
|
738
789
|
}
|
|
739
|
-
|
|
740
|
-
this.
|
|
741
|
-
this.cardEventSubs = [];
|
|
790
|
+
ngAfterViewInit() {
|
|
791
|
+
this.outlets.changes.subscribe(() => this.subscribeToCardEvents());
|
|
742
792
|
}
|
|
743
793
|
ngOnDestroy() {
|
|
744
|
-
this.
|
|
794
|
+
this.clearCardEventSubs();
|
|
745
795
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
this.
|
|
749
|
-
this.
|
|
750
|
-
|
|
751
|
-
const lessons = await this.lessonsService.getLessons(paginator);
|
|
752
|
-
this.lessons = lessons['rows'] || lessons;
|
|
753
|
-
this.totalRecords = lessons['count'] || this.lessons.length;
|
|
754
|
-
console.log('lessons', lessons);
|
|
755
|
-
setTimeout(() => {
|
|
756
|
-
this.subscribeDinamicInstantToEvents();
|
|
757
|
-
});
|
|
758
|
-
}
|
|
759
|
-
finally {
|
|
760
|
-
this.isLoadingLessons = false;
|
|
761
|
-
this.cdr.detectChanges();
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
search(searchText) {
|
|
765
|
-
this.filterConfig['text'] = searchText;
|
|
766
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
796
|
+
getCustomButtons(item) {
|
|
797
|
+
return [
|
|
798
|
+
{ label: 'Select', icon: 'pi pi-check', command: () => this.handleAction({ action: 'select', item }) },
|
|
799
|
+
{ label: 'QR', icon: 'pi pi-qrcode', command: () => this.handleAction({ action: 'qr', item }) },
|
|
800
|
+
];
|
|
767
801
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
this.toastrService.success({ title: 'Adios a la lección', subtitle: 'La lección ha sido eliminada correctamente' });
|
|
802
|
+
handleAction(actionEvent) {
|
|
803
|
+
if (['select', 'qr'].includes(actionEvent.action)) {
|
|
804
|
+
this.onAction.emit(actionEvent);
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
super.doAction(actionEvent);
|
|
775
808
|
}
|
|
776
|
-
}
|
|
777
|
-
newLesson() {
|
|
778
|
-
this.onAction.emit({ action: 'new' });
|
|
779
809
|
}
|
|
780
810
|
applyFilterBarEvent(filterEvent) {
|
|
781
|
-
if (filterEvent.action
|
|
782
|
-
this.
|
|
811
|
+
if (filterEvent.action === 'changeView') {
|
|
812
|
+
this.toggleView();
|
|
783
813
|
return;
|
|
784
814
|
}
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
this.filterConfig = filterEvent.item;
|
|
788
|
-
this.filterConfig.returnProps = returnProperties;
|
|
789
|
-
this.getPaginatedLessons(this.filterConfig);
|
|
790
|
-
}
|
|
815
|
+
this.filterConfig = { ...this.filterConfig, ...filterEvent.item };
|
|
816
|
+
this.loadData();
|
|
791
817
|
}
|
|
792
|
-
|
|
793
|
-
|
|
818
|
+
subscribeToCardEvents() {
|
|
819
|
+
this.clearCardEventSubs();
|
|
820
|
+
this.outlets.forEach((outlet) => {
|
|
821
|
+
const instance = outlet.componentInstance;
|
|
822
|
+
if (instance?.onAction) {
|
|
823
|
+
this.cardEventSubs.push(instance.onAction.subscribe((event) => {
|
|
824
|
+
this.handleAction(event);
|
|
825
|
+
}));
|
|
826
|
+
}
|
|
827
|
+
});
|
|
794
828
|
}
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
829
|
+
clearCardEventSubs() {
|
|
830
|
+
this.cardEventSubs.forEach((sub) => sub.unsubscribe());
|
|
831
|
+
this.cardEventSubs = [];
|
|
832
|
+
}
|
|
833
|
+
async loadData() {
|
|
834
|
+
try {
|
|
835
|
+
this.isLoading = true;
|
|
836
|
+
const response = await this.entityCommunicationService.getLessons(this.filterConfig);
|
|
837
|
+
this.items.set(response.rows);
|
|
838
|
+
this.totalRecordsSignal.set(response.count);
|
|
798
839
|
}
|
|
799
|
-
|
|
800
|
-
|
|
840
|
+
catch (error) {
|
|
841
|
+
console.error('Error loading data', error);
|
|
842
|
+
}
|
|
843
|
+
finally {
|
|
844
|
+
this.isLoading = false;
|
|
801
845
|
}
|
|
802
846
|
}
|
|
803
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
804
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
847
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
848
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DCLessonListComponent, isStandalone: true, selector: "dc-lesson-list", inputs: { customCardComponent: "customCardComponent", customFilters: "customFilters" }, viewQueries: [{ propertyName: "outlets", predicate: ["outlet"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<dc-filter-bar [options]=\"filterBarOptions\" [customFilters]=\"customFilters\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n@if(viewType() === 'table') {\n\n<app-quick-table [tableData]=\"items()\" (onAction)=\"doAction($event)\"></app-quick-table>\n\n} @else {\n<div class=\"lesson-list-container\">\n @if (items()?.length > 0) { @for (lesson of items(); track lesson._id) {\n <ng-container\n #outlet=\"ngComponentOutlet\"\n [ngComponentOutlet]=\"cardComponent\"\n [ngComponentOutletInputs]=\"{\n lesson: lesson,\n showOptions: true\n }\">\n </ng-container>\n\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 [totalRecords]=\"totalRecords\"\n [first]=\"first\"\n [rows]=\"rows\"\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: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$2.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }] }); }
|
|
805
849
|
}
|
|
806
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
850
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonListComponent, decorators: [{
|
|
807
851
|
type: Component,
|
|
808
|
-
args: [{ selector: 'dc-lesson-list', standalone: true, imports: [RouterModule, DCFilterBarComponent,
|
|
809
|
-
}], propDecorators: {
|
|
810
|
-
type: Input
|
|
811
|
-
}], customCardComponent: [{
|
|
852
|
+
args: [{ selector: 'dc-lesson-list', standalone: true, imports: [RouterModule, DCFilterBarComponent, NgComponentOutlet, QuickTableComponent, PaginatorModule], template: "<dc-filter-bar [options]=\"filterBarOptions\" [customFilters]=\"customFilters\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n@if(viewType() === 'table') {\n\n<app-quick-table [tableData]=\"items()\" (onAction)=\"doAction($event)\"></app-quick-table>\n\n} @else {\n<div class=\"lesson-list-container\">\n @if (items()?.length > 0) { @for (lesson of items(); track lesson._id) {\n <ng-container\n #outlet=\"ngComponentOutlet\"\n [ngComponentOutlet]=\"cardComponent\"\n [ngComponentOutletInputs]=\"{\n lesson: lesson,\n showOptions: true\n }\">\n </ng-container>\n\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 [totalRecords]=\"totalRecords\"\n [first]=\"first\"\n [rows]=\"rows\"\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"] }]
|
|
853
|
+
}], ctorParameters: () => [], propDecorators: { customCardComponent: [{
|
|
812
854
|
type: Input
|
|
813
855
|
}], customFilters: [{
|
|
814
856
|
type: Input
|
|
815
|
-
}], viewType: [{
|
|
816
|
-
type: Input
|
|
817
857
|
}], outlets: [{
|
|
818
858
|
type: ViewChildren,
|
|
819
859
|
args: ['outlet']
|
|
820
860
|
}] } });
|
|
821
861
|
|
|
822
862
|
class DCLessonFormComponent {
|
|
823
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
824
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
863
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
864
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: DCLessonFormComponent, isStandalone: true, selector: "dc-lesson-form", ngImport: i0, template: "<div class=\"lesson-form-container\">\n <h2>Lesson Form</h2>\n <p>Esto es dentro del componente de la leccion</p>\n <!-- Form implementation will go here -->\n</div>\n", styles: [".lesson-form-container{padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }] }); }
|
|
825
865
|
}
|
|
826
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
866
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonFormComponent, decorators: [{
|
|
827
867
|
type: Component,
|
|
828
868
|
args: [{ selector: 'dc-lesson-form', standalone: true, imports: [ReactiveFormsModule], template: "<div class=\"lesson-form-container\">\n <h2>Lesson Form</h2>\n <p>Esto es dentro del componente de la leccion</p>\n <!-- Form implementation will go here -->\n</div>\n", styles: [".lesson-form-container{padding:1rem}\n"] }]
|
|
829
869
|
}] });
|
|
@@ -843,7 +883,6 @@ const DEFAULT_LESSON_AGENT_CARD = {
|
|
|
843
883
|
post_history_instructions: 'Your reply should be always short, 1 or 2 paragraphs at most, and to the point, and you should ask friendly questions all the time',
|
|
844
884
|
},
|
|
845
885
|
},
|
|
846
|
-
model: { provider: 'google' },
|
|
847
886
|
};
|
|
848
887
|
const AppRolePlaySkill = `
|
|
849
888
|
You are an app role play assistant from Polilan App. The user is reading lessons through this app interface. They will now talk with you, and you need to evaluate their understanding of the lesson.
|
|
@@ -854,14 +893,13 @@ You are an engagement assistant, start by greeting the user, asking something ab
|
|
|
854
893
|
that makes sense for the lesson.
|
|
855
894
|
`;
|
|
856
895
|
function getDefaultLessonEvaluatorAgentCard(lessonText) {
|
|
896
|
+
// TODO: probably i need to build in order to add the sources to the task or system.
|
|
857
897
|
return {
|
|
858
898
|
expectedResponseType: `interface EvalResult {
|
|
859
899
|
score: number; // Score of the user's response 0 to 3
|
|
860
900
|
feedback: string; // Feedback of the user's understanding of the conversation
|
|
861
901
|
}`,
|
|
862
|
-
messages: [],
|
|
863
902
|
model: { id: 'gpt-4o-mini', provider: 'openai' },
|
|
864
|
-
sources: [lessonText],
|
|
865
903
|
task: `User is reading a taking a lesson, now their are having a conversation,
|
|
866
904
|
you have to evaluate the current conversation, and give a feedback of the user understanding of the lesson,
|
|
867
905
|
this is the lesson: ${lessonText}`,
|
|
@@ -869,8 +907,7 @@ function getDefaultLessonEvaluatorAgentCard(lessonText) {
|
|
|
869
907
|
}
|
|
870
908
|
class LessonAIService {
|
|
871
909
|
constructor() {
|
|
872
|
-
this.
|
|
873
|
-
// TODO: Inject the application-level UserService
|
|
910
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
874
911
|
this.userService = inject(USER_DATA_EXCHANGE);
|
|
875
912
|
}
|
|
876
913
|
/**
|
|
@@ -894,7 +931,7 @@ ${userInformationPrompt}`;
|
|
|
894
931
|
* @returns An object containing the master agent card and the evaluator agent card.
|
|
895
932
|
*/
|
|
896
933
|
async generateAgentCards(lesson) {
|
|
897
|
-
const lessonText = this.
|
|
934
|
+
const lessonText = this.lessonsService.extractTextFromHtml(lesson.textCoded);
|
|
898
935
|
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
899
936
|
const scenario = this._buildScenarioPrompt(lessonText, userInformationPrompt);
|
|
900
937
|
// Create a deep copy of the default card to avoid modifying the constant
|
|
@@ -912,7 +949,7 @@ ${userInformationPrompt}`;
|
|
|
912
949
|
async generateConversationSettingsForLesson(lesson, settings) {
|
|
913
950
|
// TODO: Consolidate user fetching logic if possible, or ensure consistency
|
|
914
951
|
const baseLang = this.userService.getUserDataExchange()?.baseLang || 'en';
|
|
915
|
-
const lessonText = this.
|
|
952
|
+
const lessonText = this.lessonsService.extractTextFromHtml(lesson.textCoded);
|
|
916
953
|
const userInformationPrompt = this.userService.getUserDataInformation();
|
|
917
954
|
let scenario = this._buildScenarioPrompt(lessonText, userInformationPrompt);
|
|
918
955
|
if (settings.additionalPrompt) {
|
|
@@ -921,6 +958,7 @@ ${userInformationPrompt}`;
|
|
|
921
958
|
const initialMessage = {
|
|
922
959
|
role: ChatRole.System,
|
|
923
960
|
content: scenario,
|
|
961
|
+
messageId: SystemPromptType.SystemPrompt,
|
|
924
962
|
};
|
|
925
963
|
// Use defaults similar to DEFAULT_LESSON_AGENT_CARD but adjust for prompt-based start
|
|
926
964
|
const conversationSettings = {
|
|
@@ -929,14 +967,14 @@ ${userInformationPrompt}`;
|
|
|
929
967
|
autoStart: true,
|
|
930
968
|
messages: [initialMessage],
|
|
931
969
|
model: { provider: 'google' },
|
|
932
|
-
voice: getRandomQuickVoice(baseLang || 'en', 'female'),
|
|
970
|
+
tts: { voice: getRandomQuickVoice(baseLang || 'en', 'female') },
|
|
933
971
|
};
|
|
934
972
|
return conversationSettings;
|
|
935
973
|
}
|
|
936
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
937
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
974
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
975
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, providedIn: 'root' }); }
|
|
938
976
|
}
|
|
939
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
977
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonAIService, decorators: [{
|
|
940
978
|
type: Injectable,
|
|
941
979
|
args: [{
|
|
942
980
|
providedIn: 'root', // Or provide appropriately if it's library-specific
|
|
@@ -994,10 +1032,10 @@ class DynamicComponentsService {
|
|
|
994
1032
|
getDynamicComponentClass(type) {
|
|
995
1033
|
return this._dynamicComponents[type];
|
|
996
1034
|
}
|
|
997
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
998
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1035
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1036
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsService, providedIn: 'root' }); }
|
|
999
1037
|
}
|
|
1000
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1038
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsService, decorators: [{
|
|
1001
1039
|
type: Injectable,
|
|
1002
1040
|
args: [{
|
|
1003
1041
|
providedIn: 'root',
|
|
@@ -1007,29 +1045,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1007
1045
|
class DCLessonRendererComponent {
|
|
1008
1046
|
constructor() {
|
|
1009
1047
|
// --- Signal Inputs ---
|
|
1010
|
-
this.lessonInput = input(); // Input signal for lesson object
|
|
1011
|
-
this.lessonIdInput = input(); // Input signal for lesson ID
|
|
1012
|
-
this.settings = input();
|
|
1048
|
+
this.lessonInput = input(...(ngDevMode ? [undefined, { debugName: "lessonInput" }] : [])); // Input signal for lesson object
|
|
1049
|
+
this.lessonIdInput = input(...(ngDevMode ? [undefined, { debugName: "lessonIdInput" }] : [])); // Input signal for lesson ID
|
|
1050
|
+
this.settings = input(...(ngDevMode ? [undefined, { debugName: "settings" }] : []));
|
|
1013
1051
|
// --- Outputs ---
|
|
1014
1052
|
this.wordClicked = new EventEmitter(); // New output event
|
|
1015
1053
|
// --- Services ---
|
|
1016
1054
|
this.renderer = inject(Renderer2);
|
|
1017
1055
|
this.viewContainerRef = inject(ViewContainerRef);
|
|
1018
1056
|
this.toastrService = inject(TOAST_ALERTS_TOKEN);
|
|
1019
|
-
this.
|
|
1057
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
1020
1058
|
this.lessonAIService = inject(LessonAIService); // Inject the new service
|
|
1021
1059
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
1022
1060
|
this.dynamicComponentsService = inject(DynamicComponentsService);
|
|
1061
|
+
this.uiStateService = inject(UiStateService);
|
|
1023
1062
|
// --- State Signals ---
|
|
1024
|
-
this.lesson = signal(undefined); // Internal lesson state signal
|
|
1025
|
-
|
|
1026
|
-
this.agentMasterLesson = signal(undefined); // Signal for agent card
|
|
1027
|
-
this.evaluatorAgentCard = signal(undefined); // Signal for evaluator card
|
|
1028
|
-
this.conversationSettings = signal(undefined);
|
|
1029
|
-
this.evalAgentTask = signal(undefined); // Signal for evaluator card
|
|
1030
|
-
|
|
1063
|
+
this.lesson = signal(undefined, ...(ngDevMode ? [{ debugName: "lesson" }] : [])); // Internal lesson state signal
|
|
1064
|
+
// chatVisible = this.uiStateService.chatDrawerVisible; // Signal for chat visibility
|
|
1065
|
+
this.agentMasterLesson = signal(undefined, ...(ngDevMode ? [{ debugName: "agentMasterLesson" }] : [])); // Signal for agent card
|
|
1066
|
+
this.evaluatorAgentCard = signal(undefined, ...(ngDevMode ? [{ debugName: "evaluatorAgentCard" }] : [])); // Signal for evaluator card
|
|
1067
|
+
this.conversationSettings = signal(undefined, ...(ngDevMode ? [{ debugName: "conversationSettings" }] : []));
|
|
1068
|
+
this.evalAgentTask = signal(undefined, ...(ngDevMode ? [{ debugName: "evalAgentTask" }] : [])); // Signal for evaluator card
|
|
1069
|
+
// backgroundTasks: Record<ConversationEvents | string, SimpleAgentTask> = {};
|
|
1070
|
+
this.conversationFlow = signal(undefined, ...(ngDevMode ? [{ debugName: "conversationFlow" }] : []));
|
|
1031
1071
|
// --- Computed Signals ---
|
|
1032
|
-
this.imageCover = computed(() => this.lesson()?.media?.images?.find((img) => img.type === 'cover')?.url); // Computed signal for imageCover
|
|
1072
|
+
this.imageCover = computed(() => this.lesson()?.media?.images?.find((img) => img.type === 'cover')?.url, ...(ngDevMode ? [{ debugName: "imageCover" }] : [])); // Computed signal for imageCover
|
|
1033
1073
|
// --- Properties ---
|
|
1034
1074
|
this.components = {};
|
|
1035
1075
|
this.mainForm = new FormGroup({});
|
|
@@ -1046,7 +1086,7 @@ class DCLessonRendererComponent {
|
|
|
1046
1086
|
console.log(`[Renderer] Effect 1: Fetching lesson ${lessonId}`);
|
|
1047
1087
|
try {
|
|
1048
1088
|
// Consider adding a loading state signal here
|
|
1049
|
-
const fetchedLesson = await this.
|
|
1089
|
+
const fetchedLesson = await this.lessonsService.getLesson(lessonId);
|
|
1050
1090
|
this.lesson.set(fetchedLesson);
|
|
1051
1091
|
console.log('Fetched lesson:', fetchedLesson);
|
|
1052
1092
|
}
|
|
@@ -1091,9 +1131,55 @@ class DCLessonRendererComponent {
|
|
|
1091
1131
|
});
|
|
1092
1132
|
}
|
|
1093
1133
|
ngOnInit() {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1134
|
+
// TODO: esto es mal, el goal no puede venir aqui sino pasado desde el componente que inicie la lección
|
|
1135
|
+
this.conversationFlow.set({
|
|
1136
|
+
goal: {
|
|
1137
|
+
enabled: true,
|
|
1138
|
+
task: `User is learning is taking a lesson about languages, evaluate how good are the responses.`,
|
|
1139
|
+
model: { quality: EModelQuality.FAST },
|
|
1140
|
+
},
|
|
1141
|
+
triggerTasks: {
|
|
1142
|
+
[ConversationEvents.OnUserMessage]: {
|
|
1143
|
+
enabled: true,
|
|
1144
|
+
...this.evalAgentTask(),
|
|
1145
|
+
},
|
|
1146
|
+
},
|
|
1147
|
+
challenges: null,
|
|
1148
|
+
dynamicConditions: [
|
|
1149
|
+
{
|
|
1150
|
+
what: ConditionType.Goal,
|
|
1151
|
+
when: ConditionOperator.GreaterThanOrEqual,
|
|
1152
|
+
value: 100,
|
|
1153
|
+
do: [
|
|
1154
|
+
{
|
|
1155
|
+
actionType: EDoActionType.ChangePrompt,
|
|
1156
|
+
systemPromptType: SystemPromptType.SystemPrompt,
|
|
1157
|
+
prompt: 'You were talking with the user, user finish the conversation, in the next message you must try to finish the conversation and say good bye.',
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
actionType: EDoActionType.ChangePrompt,
|
|
1161
|
+
systemPromptType: SystemPromptType.CharacterDescription,
|
|
1162
|
+
prompt: '',
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
actionType: EDoActionType.ChangePrompt,
|
|
1166
|
+
systemPromptType: SystemPromptType.UserInformation,
|
|
1167
|
+
prompt: '',
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
actionType: EDoActionType.ChangePrompt,
|
|
1171
|
+
systemPromptType: SystemPromptType.MessageExamples,
|
|
1172
|
+
prompt: '',
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
actionType: EDoActionType.ChangePrompt,
|
|
1176
|
+
systemPromptType: SystemPromptType.ScenarioDescription,
|
|
1177
|
+
prompt: '',
|
|
1178
|
+
},
|
|
1179
|
+
],
|
|
1180
|
+
},
|
|
1181
|
+
],
|
|
1182
|
+
});
|
|
1097
1183
|
}
|
|
1098
1184
|
// --- Rendering Logic ---
|
|
1099
1185
|
_clearLessonRendering() {
|
|
@@ -1279,7 +1365,7 @@ class DCLessonRendererComponent {
|
|
|
1279
1365
|
const conversationSettings = await this.lessonAIService.generateConversationSettingsForLesson(currentLesson, this.settings());
|
|
1280
1366
|
if (conversationSettings) {
|
|
1281
1367
|
this.conversationSettings.set(conversationSettings);
|
|
1282
|
-
this.
|
|
1368
|
+
this.uiStateService.chatDrawerVisible.set(true);
|
|
1283
1369
|
console.log('Agent cards received and set.');
|
|
1284
1370
|
}
|
|
1285
1371
|
else {
|
|
@@ -1294,14 +1380,17 @@ class DCLessonRendererComponent {
|
|
|
1294
1380
|
}
|
|
1295
1381
|
onVisibleChange(isVisible) {
|
|
1296
1382
|
if (isVisible === false) {
|
|
1297
|
-
this.
|
|
1383
|
+
this.uiStateService.chatDrawerVisible.set(false);
|
|
1298
1384
|
}
|
|
1299
1385
|
}
|
|
1300
|
-
handleGoalCompleted(event) {
|
|
1386
|
+
async handleGoalCompleted(event = {}) {
|
|
1301
1387
|
console.log('Goal completed:', event);
|
|
1302
1388
|
const lesson = this.lesson();
|
|
1303
|
-
const
|
|
1304
|
-
this.
|
|
1389
|
+
const takenLesson = { id: lesson.id, goalCompleted: true, score: 100, status: 'finished', lastAccess: new Date() };
|
|
1390
|
+
const res = await this.lessonsService.saveTakenLesson(takenLesson);
|
|
1391
|
+
if (res) {
|
|
1392
|
+
// this.lessonsMemStateService.updateUserState(res);
|
|
1393
|
+
}
|
|
1305
1394
|
this.toastrService.success({ subtitle: '¡Has completado la lección! , pero puedes seguir conversando', title: '¡Muy bien, guardaremos tu progreso!' });
|
|
1306
1395
|
}
|
|
1307
1396
|
onChatMessage(event) {
|
|
@@ -1318,12 +1407,12 @@ class DCLessonRendererComponent {
|
|
|
1318
1407
|
console.log('Unhandled chat event type:', event.type);
|
|
1319
1408
|
}
|
|
1320
1409
|
}
|
|
1321
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1322
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
1410
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1411
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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(uiStateService.chatDrawerVisible()) {\n<p-drawer\n header=\"Conversation\"\n [visible]=\"uiStateService.chatDrawerVisible()\"\n (visibleChange)=\"onVisibleChange($event)\"\n position=\"bottom\"\n styleClass=\"app-bottom-overlay\">\n <dc-chat\n [conversationFlow]=\"conversationFlow()\"\n [conversationSettings]=\"conversationSettings()\"\n (goalCompleted)=\"handleGoalCompleted($event)\"\n (chatEvent)=\"onChatMessage($event)\"></dc-chat>\n</p-drawer>\n}\n", styles: ["::ng-deep .targetclass *:not(h1,h2,h3,h4,h5,h6){font-family:\"math\",sans-serif,system-ui,monospace!important}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCChatComponent, selector: "dc-chat", inputs: ["chatUserSettings", "conversationSettings", "conversationFlow", "agentCard", "parseDict"], outputs: ["chatEvent", "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"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }] }); }
|
|
1323
1412
|
}
|
|
1324
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1413
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonRendererComponent, decorators: [{
|
|
1325
1414
|
type: Component,
|
|
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(
|
|
1415
|
+
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(uiStateService.chatDrawerVisible()) {\n<p-drawer\n header=\"Conversation\"\n [visible]=\"uiStateService.chatDrawerVisible()\"\n (visibleChange)=\"onVisibleChange($event)\"\n position=\"bottom\"\n styleClass=\"app-bottom-overlay\">\n <dc-chat\n [conversationFlow]=\"conversationFlow()\"\n [conversationSettings]=\"conversationSettings()\"\n (goalCompleted)=\"handleGoalCompleted($event)\"\n (chatEvent)=\"onChatMessage($event)\"></dc-chat>\n</p-drawer>\n}\n", styles: ["::ng-deep .targetclass *:not(h1,h2,h3,h4,h5,h6){font-family:\"math\",sans-serif,system-ui,monospace!important}\n"] }]
|
|
1327
1416
|
}], ctorParameters: () => [], propDecorators: { wordClicked: [{
|
|
1328
1417
|
type: Output
|
|
1329
1418
|
}], dynamicLesson: [{
|
|
@@ -1334,13 +1423,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1334
1423
|
class LessonNotionService {
|
|
1335
1424
|
constructor() {
|
|
1336
1425
|
this.#notionService = inject(NOTION_SERVICE_TOKEN);
|
|
1337
|
-
this
|
|
1426
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
1338
1427
|
this.#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1339
1428
|
// Keep track of loading state specific to Notion operations
|
|
1340
|
-
this.isLoading = signal(false);
|
|
1429
|
+
this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
1341
1430
|
}
|
|
1342
1431
|
#notionService;
|
|
1343
|
-
#lessonService;
|
|
1344
1432
|
#toastService;
|
|
1345
1433
|
/**
|
|
1346
1434
|
* Extracts the Notion Page ID from a URL.
|
|
@@ -1374,14 +1462,17 @@ class LessonNotionService {
|
|
|
1374
1462
|
}
|
|
1375
1463
|
const updatedLesson = {
|
|
1376
1464
|
...lesson,
|
|
1377
|
-
|
|
1378
|
-
...(lesson.
|
|
1379
|
-
|
|
1465
|
+
extensions: {
|
|
1466
|
+
...(lesson.extensions || {}),
|
|
1467
|
+
extras: {
|
|
1468
|
+
...(lesson.extensions?.['extras'] || {}),
|
|
1469
|
+
notionPageId: notionPageId,
|
|
1470
|
+
},
|
|
1380
1471
|
},
|
|
1381
1472
|
};
|
|
1382
1473
|
this.isLoading.set(true);
|
|
1383
1474
|
try {
|
|
1384
|
-
const savedLesson = await this
|
|
1475
|
+
const savedLesson = await this.lessonsService.postLesson(updatedLesson);
|
|
1385
1476
|
this.#toastService.success({ title: 'Listo', subtitle: 'Se enlazó la lección con Notion.' });
|
|
1386
1477
|
return savedLesson;
|
|
1387
1478
|
}
|
|
@@ -1407,10 +1498,10 @@ class LessonNotionService {
|
|
|
1407
1498
|
if (!currentLesson)
|
|
1408
1499
|
return null;
|
|
1409
1500
|
let notionPageId = null;
|
|
1410
|
-
if (currentLesson.extras?.notionPageId) {
|
|
1411
|
-
const useExisting = confirm(`Ya tenemos el id ${currentLesson.extras
|
|
1501
|
+
if (currentLesson.extensions?.['extras']?.['notionPageId']) {
|
|
1502
|
+
const useExisting = confirm(`Ya tenemos el id ${currentLesson.extensions?.['extras']?.['notionPageId']} ¿Quieres usar este id para importar?`);
|
|
1412
1503
|
if (useExisting) {
|
|
1413
|
-
notionPageId = currentLesson.extras
|
|
1504
|
+
notionPageId = currentLesson.extensions?.['extras']?.['notionPageId'];
|
|
1414
1505
|
}
|
|
1415
1506
|
else {
|
|
1416
1507
|
const inputUrl = prompt('Ingresa la NUEVA URL de Notion para importar (este ID NO se guardará automáticamente si la lección ya existe)');
|
|
@@ -1465,7 +1556,7 @@ class LessonNotionService {
|
|
|
1465
1556
|
async improveLessonWithNotionAI(lesson) {
|
|
1466
1557
|
if (!lesson)
|
|
1467
1558
|
return;
|
|
1468
|
-
const notionId = lesson.extras?.notionPageId;
|
|
1559
|
+
const notionId = lesson.extensions?.['extras']?.['notionPageId'];
|
|
1469
1560
|
if (!notionId) {
|
|
1470
1561
|
this.#toastService.warn({ title: 'Sin ID de Notion', subtitle: 'Enlaza la lección con Notion primero.' });
|
|
1471
1562
|
return;
|
|
@@ -1489,22 +1580,21 @@ class LessonNotionService {
|
|
|
1489
1580
|
this.isLoading.set(false);
|
|
1490
1581
|
}
|
|
1491
1582
|
}
|
|
1492
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1493
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1583
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonNotionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1584
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonNotionService }); }
|
|
1494
1585
|
}
|
|
1495
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonNotionService, decorators: [{
|
|
1496
1587
|
type: Injectable
|
|
1497
1588
|
}] });
|
|
1498
1589
|
|
|
1499
1590
|
// import { UserDataExchangeService } from '@dataclouder/ngx-agent-cards';
|
|
1500
1591
|
class LessonUtilsService {
|
|
1501
1592
|
constructor() {
|
|
1502
|
-
this
|
|
1593
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
1503
1594
|
this.#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1504
1595
|
this.#agentService = inject(CONVERSATION_AI_TOKEN);
|
|
1505
1596
|
this.loadingBarService = inject(LoadingBarService);
|
|
1506
1597
|
}
|
|
1507
|
-
#lessonService;
|
|
1508
1598
|
#toastService;
|
|
1509
1599
|
#agentService;
|
|
1510
1600
|
/**
|
|
@@ -1529,10 +1619,11 @@ class LessonUtilsService {
|
|
|
1529
1619
|
lessonSignal.update((currentLesson) => {
|
|
1530
1620
|
if (!currentLesson)
|
|
1531
1621
|
return undefined;
|
|
1532
|
-
const
|
|
1622
|
+
const assets = { ...(currentLesson.assets ?? {}) };
|
|
1623
|
+
assets.banner = imageUploaded;
|
|
1533
1624
|
return {
|
|
1534
1625
|
...currentLesson,
|
|
1535
|
-
|
|
1626
|
+
assets,
|
|
1536
1627
|
};
|
|
1537
1628
|
});
|
|
1538
1629
|
}
|
|
@@ -1550,9 +1641,9 @@ class LessonUtilsService {
|
|
|
1550
1641
|
}
|
|
1551
1642
|
// No need to save here, component should ensure it's saved before calling.
|
|
1552
1643
|
try {
|
|
1553
|
-
await this
|
|
1644
|
+
await this.lessonsService.postGenerateByAI(lessonId);
|
|
1554
1645
|
// Re-fetch the lesson data to get AI updates
|
|
1555
|
-
const updatedLesson = await this
|
|
1646
|
+
const updatedLesson = await this.lessonsService.getLesson(lessonId);
|
|
1556
1647
|
if (updatedLesson) {
|
|
1557
1648
|
this.#toastService.success({ title: 'IA completada', subtitle: 'Lección actualizada con IA.' });
|
|
1558
1649
|
return updatedLesson;
|
|
@@ -1583,7 +1674,7 @@ class LessonUtilsService {
|
|
|
1583
1674
|
}
|
|
1584
1675
|
try {
|
|
1585
1676
|
this.loadingBarService.showIndeterminate();
|
|
1586
|
-
const textPrompt = this
|
|
1677
|
+
const textPrompt = this.lessonsService.getPrompts().content(lesson);
|
|
1587
1678
|
const messages = [{ content: textPrompt, role: ChatRole.User }];
|
|
1588
1679
|
const response = await this.#agentService.callChatCompletion({ messages, model: { provider: 'google' } });
|
|
1589
1680
|
let improvedMarkdown = response.content?.trim() ?? null;
|
|
@@ -1635,7 +1726,7 @@ class LessonUtilsService {
|
|
|
1635
1726
|
this.#toastService.warn({ title: 'Texto Vacío', subtitle: 'No se pudo extraer texto útil del contenido de la lección.' });
|
|
1636
1727
|
return null;
|
|
1637
1728
|
}
|
|
1638
|
-
const descriptionPrompt = this
|
|
1729
|
+
const descriptionPrompt = this.lessonsService.getPrompts().description(lesson);
|
|
1639
1730
|
const messages = [{ content: descriptionPrompt, role: ChatRole.User }];
|
|
1640
1731
|
const response = await this.#agentService.callChatCompletion({ messages, model: { provider: 'google' } });
|
|
1641
1732
|
let generatedDescription = response.content?.trim() ?? null;
|
|
@@ -1742,10 +1833,10 @@ class LessonUtilsService {
|
|
|
1742
1833
|
dynamicComponents: cleanedDynamicComponents,
|
|
1743
1834
|
};
|
|
1744
1835
|
}
|
|
1745
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1746
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1836
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonUtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1837
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonUtilsService, providedIn: 'root' }); }
|
|
1747
1838
|
}
|
|
1748
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1839
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonUtilsService, decorators: [{
|
|
1749
1840
|
type: Injectable,
|
|
1750
1841
|
args: [{
|
|
1751
1842
|
providedIn: 'root', // Provide globally or in a specific module if preferred
|
|
@@ -1775,10 +1866,10 @@ class DynamicComponentsBuilderService {
|
|
|
1775
1866
|
});
|
|
1776
1867
|
return dialogRef;
|
|
1777
1868
|
}
|
|
1778
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1779
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
1869
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1870
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsBuilderService, providedIn: 'root' }); }
|
|
1780
1871
|
}
|
|
1781
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1872
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DynamicComponentsBuilderService, decorators: [{
|
|
1782
1873
|
type: Injectable,
|
|
1783
1874
|
args: [{
|
|
1784
1875
|
providedIn: 'root',
|
|
@@ -1812,10 +1903,10 @@ class DCLessonComponentAdderComponent {
|
|
|
1812
1903
|
console.warn(`Dialog could not be opened for type via component: ${type}`);
|
|
1813
1904
|
}
|
|
1814
1905
|
}
|
|
1815
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1816
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
1906
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonComponentAdderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1907
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }] }); }
|
|
1817
1908
|
}
|
|
1818
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1909
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonComponentAdderComponent, decorators: [{
|
|
1819
1910
|
type: Component,
|
|
1820
1911
|
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" }]
|
|
1821
1912
|
}], propDecorators: { componentAdded: [{
|
|
@@ -1825,8 +1916,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1825
1916
|
class DCLessonMetadataEditorComponent {
|
|
1826
1917
|
constructor() {
|
|
1827
1918
|
// Use signal for input lesson data
|
|
1828
|
-
this.lesson = signal(undefined); // The lesson data itself
|
|
1829
|
-
this.isLoadingLesson = signal(false); // Shared loading state
|
|
1919
|
+
this.lesson = signal(undefined, ...(ngDevMode ? [{ debugName: "lesson" }] : [])); // The lesson data itself
|
|
1920
|
+
this.isLoadingLesson = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingLesson" }] : [])); // Shared loading state
|
|
1830
1921
|
// Outputs for actions
|
|
1831
1922
|
this.saveRequest = new EventEmitter();
|
|
1832
1923
|
this.importNotionRequest = new EventEmitter();
|
|
@@ -1837,7 +1928,7 @@ class DCLessonMetadataEditorComponent {
|
|
|
1837
1928
|
// Injected Services
|
|
1838
1929
|
this.#lessonUtilsService = inject(LessonUtilsService);
|
|
1839
1930
|
this.#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1840
|
-
this
|
|
1931
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
1841
1932
|
this.#turndownService = new TurndownService(); // Instantiate TurndownService
|
|
1842
1933
|
}
|
|
1843
1934
|
// Removed generateAIRequest Output as it's handled internally now
|
|
@@ -1846,7 +1937,6 @@ class DCLessonMetadataEditorComponent {
|
|
|
1846
1937
|
// Injected Services
|
|
1847
1938
|
#lessonUtilsService;
|
|
1848
1939
|
#toastService;
|
|
1849
|
-
#lessonService;
|
|
1850
1940
|
#turndownService; // Instantiate TurndownService
|
|
1851
1941
|
// Method to handle property changes for ROOT properties (e.g., level)
|
|
1852
1942
|
onRootPropertyChange(property, value) {
|
|
@@ -1854,24 +1944,15 @@ class DCLessonMetadataEditorComponent {
|
|
|
1854
1944
|
if (!current)
|
|
1855
1945
|
return undefined;
|
|
1856
1946
|
// Avoid updating metadata directly here
|
|
1857
|
-
if (property === 'metadata') {
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}
|
|
1947
|
+
// if (property === 'metadata') {
|
|
1948
|
+
// console.warn('Direct metadata updates should use onMetadataPropertyChange');
|
|
1949
|
+
// return current;
|
|
1950
|
+
// }
|
|
1861
1951
|
return { ...current, [property]: value };
|
|
1862
1952
|
});
|
|
1863
1953
|
// Emit removed - signal is updated directly above.
|
|
1864
1954
|
// this.propertyChange.emit({ propertyPath: property, value });
|
|
1865
1955
|
}
|
|
1866
|
-
// Method to handle property changes for METADATA properties
|
|
1867
|
-
onMetadataPropertyChange(property, value) {
|
|
1868
|
-
this.lesson.update((current) => {
|
|
1869
|
-
if (!current)
|
|
1870
|
-
return undefined;
|
|
1871
|
-
const updatedMetadata = { ...(current.metadata ?? {}), [property]: value };
|
|
1872
|
-
return { ...current, metadata: updatedMetadata };
|
|
1873
|
-
});
|
|
1874
|
-
}
|
|
1875
1956
|
// Method to handle property changes for APP EXTENSION properties
|
|
1876
1957
|
onAppExtensionPropChange(property, value) {
|
|
1877
1958
|
this.lesson.update((current) => {
|
|
@@ -1880,8 +1961,24 @@ class DCLessonMetadataEditorComponent {
|
|
|
1880
1961
|
// Ensure appExtension exists, initialize if not
|
|
1881
1962
|
// Convert value to number specifically for 'level'
|
|
1882
1963
|
const finalValue = property === 'level' ? Number(value) : value;
|
|
1883
|
-
const updatedAppExtension = { ...(current.
|
|
1884
|
-
return { ...current,
|
|
1964
|
+
const updatedAppExtension = { ...(current.extensions ?? {}), [property]: finalValue };
|
|
1965
|
+
return { ...current, extensions: updatedAppExtension };
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1968
|
+
onManageablePropertyChange(property, value) {
|
|
1969
|
+
this.lesson.update((current) => {
|
|
1970
|
+
if (!current)
|
|
1971
|
+
return undefined;
|
|
1972
|
+
const updatedManageable = { ...(current.manageable ?? {}), [property]: value };
|
|
1973
|
+
return { ...current, manageable: updatedManageable };
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
onAuditablePropertyChange(property, value) {
|
|
1977
|
+
this.lesson.update((current) => {
|
|
1978
|
+
if (!current)
|
|
1979
|
+
return undefined;
|
|
1980
|
+
const updatedAuditable = { ...(current.auditable ?? {}), [property]: value };
|
|
1981
|
+
return { ...current, auditable: updatedAuditable };
|
|
1885
1982
|
});
|
|
1886
1983
|
}
|
|
1887
1984
|
// Methods to emit action requests
|
|
@@ -1917,7 +2014,7 @@ class DCLessonMetadataEditorComponent {
|
|
|
1917
2014
|
else {
|
|
1918
2015
|
// Clean orphaned and Save before Improve
|
|
1919
2016
|
const lessonToSave = this.#lessonUtilsService.cleanOrphanedComponents(currentLesson);
|
|
1920
|
-
const savedLesson = await this
|
|
2017
|
+
const savedLesson = await this.lessonsService.postLesson(lessonToSave);
|
|
1921
2018
|
if (!savedLesson) {
|
|
1922
2019
|
this.#toastService.error({ title: 'Error al guardar', subtitle: 'No se pudo guardar antes de generar con IA.' });
|
|
1923
2020
|
throw new Error('Failed to save before AI generation');
|
|
@@ -1980,7 +2077,7 @@ class DCLessonMetadataEditorComponent {
|
|
|
1980
2077
|
// Ensure lesson() is not undefined before saving
|
|
1981
2078
|
const lessonToSave = this.lesson();
|
|
1982
2079
|
if (lessonToSave) {
|
|
1983
|
-
await this
|
|
2080
|
+
await this.lessonsService.postLesson(lessonToSave);
|
|
1984
2081
|
this.#toastService.success({ title: 'Contenido generado', subtitle: 'Se generó y guardó el contenido con IA.' });
|
|
1985
2082
|
}
|
|
1986
2083
|
else {
|
|
@@ -2010,32 +2107,35 @@ class DCLessonMetadataEditorComponent {
|
|
|
2010
2107
|
}
|
|
2011
2108
|
const generatedDescription = await this.#lessonUtilsService.generateDescriptionWithAI(currentLesson);
|
|
2012
2109
|
if (generatedDescription) {
|
|
2013
|
-
|
|
2014
|
-
this.onMetadataPropertyChange('description', generatedDescription);
|
|
2110
|
+
this.lessonForm.controls['description'].setValue(generatedDescription);
|
|
2015
2111
|
}
|
|
2016
2112
|
}
|
|
2017
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2018
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2113
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonMetadataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2114
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DCLessonMetadataEditorComponent, isStandalone: true, selector: "dc-lesson-metadata-editor", inputs: { lesson: "lesson", lessonForm: "lessonForm", isLoadingLesson: "isLoadingLesson" }, outputs: { saveRequest: "saveRequest", importNotionRequest: "importNotionRequest", improveNotionRequest: "improveNotionRequest" }, ngImport: i0, template: "@if (lesson(); as currentLesson) {\n<div [formGroup]=\"lessonForm\">\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 pInputText style=\"width: 100%\" formControlName=\"title\" type=\"text\" placeholder=\"Agrega un t\u00EDtulo\" />\n </div>\n <div style=\"margin-top: 4px\">\n <p-inputgroup>\n <input pInputText style=\"width: 100%\" formControlName=\"description\" type=\"text\" placeholder=\"Agrega una descripci\u00F3n\" />\n <p-button\n icon=\"pi pi-sparkles\"\n styleClass=\"p-button-secondary p-button-outlined\"\n pTooltip=\"Generar descripci\u00F3n con IA\"\n tooltipPosition=\"top\"\n [disabled]=\"isLoadingLesson()\"\n (click)=\"triggerGenerateDescriptionAI()\" />\n </p-inputgroup>\n </div>\n\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.auditable?.prompt\"\n (ngModelChange)=\"onAuditablePropertyChange('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.manageable?.status === 'published'\"\n (ngModelChange)=\"onManageablePropertyChange('status', $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.extensions?.['level']\"\n (ngModelChange)=\"onAppExtensionPropChange('level', $event)\"\n type=\"number\"\n placeholder=\"Nivel\"\n style=\"width: 80px\" />\n\n <!-- Access signal values -->\n @if (currentLesson.extensions) {\n <div>\n {{ currentLesson.extensions?.['baseLang'] | flagEmoji }} -> {{ currentLesson.extensions?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ currentLesson.extensions?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ currentLesson.extensions?.['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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: TooltipModule }, { kind: "directive", type: i2$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: // Added Pipe
|
|
2115
|
+
InputGroupModule }, { kind: "component", type: i5.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i6.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "pipe", type: // Added TooltipModule
|
|
2019
2116
|
FlagLanguagePipe, name: "flagEmoji" }, { kind: "pipe", type: // Added Pipe
|
|
2020
|
-
LangDescTranslationPipe, name: "langDesc" }
|
|
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"] }] }); }
|
|
2117
|
+
LangDescTranslationPipe, name: "langDesc" }] }); }
|
|
2022
2118
|
}
|
|
2023
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonMetadataEditorComponent, decorators: [{
|
|
2024
2120
|
type: Component,
|
|
2025
2121
|
args: [{ selector: 'dc-lesson-metadata-editor', standalone: true, imports: [
|
|
2026
2122
|
CommonModule,
|
|
2027
2123
|
FormsModule,
|
|
2028
2124
|
ButtonModule,
|
|
2029
2125
|
InputTextModule,
|
|
2126
|
+
ReactiveFormsModule,
|
|
2030
2127
|
TooltipModule, // Added TooltipModule
|
|
2031
2128
|
FlagLanguagePipe, // Added Pipe
|
|
2032
2129
|
LangDescTranslationPipe, // Added Pipe
|
|
2033
2130
|
InputGroupModule,
|
|
2034
2131
|
DividerModule,
|
|
2035
|
-
], 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
|
|
2132
|
+
], template: "@if (lesson(); as currentLesson) {\n<div [formGroup]=\"lessonForm\">\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 pInputText style=\"width: 100%\" formControlName=\"title\" type=\"text\" placeholder=\"Agrega un t\u00EDtulo\" />\n </div>\n <div style=\"margin-top: 4px\">\n <p-inputgroup>\n <input pInputText style=\"width: 100%\" formControlName=\"description\" type=\"text\" placeholder=\"Agrega una descripci\u00F3n\" />\n <p-button\n icon=\"pi pi-sparkles\"\n styleClass=\"p-button-secondary p-button-outlined\"\n pTooltip=\"Generar descripci\u00F3n con IA\"\n tooltipPosition=\"top\"\n [disabled]=\"isLoadingLesson()\"\n (click)=\"triggerGenerateDescriptionAI()\" />\n </p-inputgroup>\n </div>\n\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.auditable?.prompt\"\n (ngModelChange)=\"onAuditablePropertyChange('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.manageable?.status === 'published'\"\n (ngModelChange)=\"onManageablePropertyChange('status', $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.extensions?.['level']\"\n (ngModelChange)=\"onAppExtensionPropChange('level', $event)\"\n type=\"number\"\n placeholder=\"Nivel\"\n style=\"width: 80px\" />\n\n <!-- Access signal values -->\n @if (currentLesson.extensions) {\n <div>\n {{ currentLesson.extensions?.['baseLang'] | flagEmoji }} -> {{ currentLesson.extensions?.['targetLang'] | flagEmoji }} Lecci\u00F3n para hablantes de\n {{ currentLesson.extensions?.['baseLang'] | langDesc : 'es' }} que aprenden\n {{ currentLesson.extensions?.['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" }]
|
|
2036
2133
|
}], propDecorators: { lesson: [{
|
|
2037
2134
|
type: Input,
|
|
2038
2135
|
args: [{ required: true }]
|
|
2136
|
+
}], lessonForm: [{
|
|
2137
|
+
type: Input,
|
|
2138
|
+
args: [{ required: true }]
|
|
2039
2139
|
}], isLoadingLesson: [{
|
|
2040
2140
|
type: Input,
|
|
2041
2141
|
args: [{ required: true }]
|
|
@@ -2047,126 +2147,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2047
2147
|
type: Output
|
|
2048
2148
|
}] } });
|
|
2049
2149
|
|
|
2050
|
-
// Define placeholder endpoints - these should be configured appropriately
|
|
2051
|
-
const LESSONS_BASE_PATH = 'api/lesson'; // Example base path
|
|
2052
|
-
class DefaultLessonsService {
|
|
2053
|
-
constructor() {
|
|
2054
|
-
this.httpCoreService = inject(HttpCoreService);
|
|
2055
|
-
// --- Endpoint Definitions (Hardcoded as requested) ---
|
|
2056
|
-
this.endpoints = {
|
|
2057
|
-
queryLessons: `${LESSONS_BASE_PATH}/query`,
|
|
2058
|
-
getLesson: (id) => `${LESSONS_BASE_PATH}/${id}`,
|
|
2059
|
-
saveLesson: `api/user/saveLesson`,
|
|
2060
|
-
updateLesson: (id) => `${LESSONS_BASE_PATH}/${id}`, // Assuming PUT to /lessons/:id
|
|
2061
|
-
deleteLesson: (id) => `${LESSONS_BASE_PATH}/${id}`, // Assuming DELETE to /lessons/:id
|
|
2062
|
-
generateLesson: `${LESSONS_BASE_PATH}/generate`, // Placeholder
|
|
2063
|
-
generateByAI: `${LESSONS_BASE_PATH}/generate-ai`, // Placeholder
|
|
2064
|
-
improveMDWithAI: `${LESSONS_BASE_PATH}/improve-markdown-ai`, // Placeholder
|
|
2065
|
-
QueryLessons: 'api/lesson/query',
|
|
2066
|
-
Lesson: 'api/lesson',
|
|
2067
|
-
SaveLesson: 'api/lesson-polilan',
|
|
2068
|
-
GetPublicLessons: 'api/lesson/publicLessons',
|
|
2069
|
-
GetUnpublishedLessons: 'api/lesson/unpublished',
|
|
2070
|
-
TakenLesson: 'api/lesson/taken',
|
|
2071
|
-
DeleteLesson: 'api/lesson',
|
|
2072
|
-
Base: 'api/lesson',
|
|
2073
|
-
GenerateBanner: 'api/lesson/generate-banner',
|
|
2074
|
-
};
|
|
2075
|
-
}
|
|
2076
|
-
saveTakenLesson(lesson) {
|
|
2077
|
-
// Not sure how to implement this yet.
|
|
2078
|
-
return this.httpCoreService.post(this.endpoints.saveLesson, lesson);
|
|
2079
|
-
}
|
|
2080
|
-
// --- Method Implementations ---
|
|
2081
|
-
async getLessons(paginator) {
|
|
2082
|
-
// Assuming paginator is the body for a POST request based on the example
|
|
2083
|
-
return this.httpCoreService.post(this.endpoints.queryLessons, paginator || {});
|
|
2084
|
-
}
|
|
2085
|
-
async getLesson(id) {
|
|
2086
|
-
return this.httpCoreService.get(this.endpoints.getLesson(id));
|
|
2087
|
-
}
|
|
2088
|
-
async postLesson(lesson) {
|
|
2089
|
-
return this.httpCoreService.post(this.endpoints.saveLesson, lesson);
|
|
2090
|
-
}
|
|
2091
|
-
async updateLesson(lesson) {
|
|
2092
|
-
if (!lesson._id) {
|
|
2093
|
-
throw new Error('Lesson ID is required for update.');
|
|
2094
|
-
}
|
|
2095
|
-
// Assuming _id is the identifier
|
|
2096
|
-
return this.httpCoreService.put(this.endpoints.updateLesson(lesson._id), lesson);
|
|
2097
|
-
}
|
|
2098
|
-
async deleteLesson(id) {
|
|
2099
|
-
return this.httpCoreService.delete(this.endpoints.deleteLesson(id));
|
|
2100
|
-
}
|
|
2101
|
-
async generateLesson(lesson) {
|
|
2102
|
-
// This endpoint might need specific data or structure
|
|
2103
|
-
return this.httpCoreService.post(this.endpoints.generateLesson, lesson);
|
|
2104
|
-
}
|
|
2105
|
-
async postGenerateByAI(id) {
|
|
2106
|
-
return this.httpCoreService.post(this.endpoints.generateByAI, { id });
|
|
2107
|
-
}
|
|
2108
|
-
async postImproveMDWithAI(lessonId, markdownText) {
|
|
2109
|
-
return this.httpCoreService.post(this.endpoints.improveMDWithAI, { id: lessonId, markdown: markdownText });
|
|
2110
|
-
}
|
|
2111
|
-
extractTextFromHtml(html) {
|
|
2112
|
-
// Copied from src/app/core/data-services/lessons.service.ts
|
|
2113
|
-
const r1 = new RegExp('~(.+?)~', 'g');
|
|
2114
|
-
const lessonHtml = html.replace(r1, (_matching, jsonCoded) => {
|
|
2115
|
-
try {
|
|
2116
|
-
const data = JSON.parse(jsonCoded);
|
|
2117
|
-
return `<span>${data?.settings?.text || ''}</span>`; // Added default empty string
|
|
2118
|
-
}
|
|
2119
|
-
catch (e) {
|
|
2120
|
-
console.error('Error parsing JSON in extractTextFromHtml:', jsonCoded, e);
|
|
2121
|
-
return ''; // Return empty string on error
|
|
2122
|
-
}
|
|
2123
|
-
});
|
|
2124
|
-
// Remove HTML tags
|
|
2125
|
-
let text = lessonHtml.replace(/<[^>]*>/g, ' ');
|
|
2126
|
-
// Remove style and script content
|
|
2127
|
-
text = text.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, ' ');
|
|
2128
|
-
text = text.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, ' ');
|
|
2129
|
-
// Decode HTML entities
|
|
2130
|
-
text = text.replace(/ /g, ' ');
|
|
2131
|
-
text = text.replace(/&/g, '&');
|
|
2132
|
-
text = text.replace(/</g, '<');
|
|
2133
|
-
text = text.replace(/>/g, '>');
|
|
2134
|
-
// Remove extra whitespace
|
|
2135
|
-
text = text.replace(/\s+/g, ' ').trim();
|
|
2136
|
-
return text;
|
|
2137
|
-
}
|
|
2138
|
-
generateBanner(prompt, lessonId) {
|
|
2139
|
-
return this.httpCoreService.post(this.endpoints.GenerateBanner, { prompt, lessonId });
|
|
2140
|
-
}
|
|
2141
|
-
getPrompts() {
|
|
2142
|
-
return null;
|
|
2143
|
-
}
|
|
2144
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DefaultLessonsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2145
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DefaultLessonsService, providedIn: 'root' }); }
|
|
2146
|
-
}
|
|
2147
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DefaultLessonsService, decorators: [{
|
|
2148
|
-
type: Injectable,
|
|
2149
|
-
args: [{
|
|
2150
|
-
providedIn: 'root',
|
|
2151
|
-
}]
|
|
2152
|
-
}] });
|
|
2153
|
-
|
|
2154
2150
|
class DCLessonEditorComponent {
|
|
2155
2151
|
// Services
|
|
2156
2152
|
#activatedRoute; // Re-inject as it's needed for navigation
|
|
2157
2153
|
#lessonNotionService;
|
|
2158
2154
|
#lessonUtilsService;
|
|
2159
2155
|
#router;
|
|
2160
|
-
#lessonService;
|
|
2161
2156
|
#toastService;
|
|
2162
2157
|
#loadingBarService;
|
|
2158
|
+
#formBuilder;
|
|
2163
2159
|
constructor() {
|
|
2164
2160
|
// Services
|
|
2165
2161
|
this.#activatedRoute = inject(ActivatedRoute); // Re-inject as it's needed for navigation
|
|
2166
2162
|
this.#lessonNotionService = inject(LessonNotionService);
|
|
2167
2163
|
this.#lessonUtilsService = inject(LessonUtilsService);
|
|
2168
2164
|
this.#router = inject(Router);
|
|
2169
|
-
this
|
|
2165
|
+
this.lessonsService = inject(LESSONS_TOKEN, { optional: true }) ?? inject(DefaultLessonsService);
|
|
2170
2166
|
this.#toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2171
2167
|
this.#loadingBarService = inject(LoadingBarService);
|
|
2172
2168
|
this.defaultLessonsService = inject(DefaultLessonsService);
|
|
@@ -2174,26 +2170,24 @@ class DCLessonEditorComponent {
|
|
|
2174
2170
|
this.ngxVertexService = inject(NgxVertexService);
|
|
2175
2171
|
this.cdr = inject(ChangeDetectorRef);
|
|
2176
2172
|
this.dynamicComponentsBuilderService = inject(DynamicComponentsBuilderService);
|
|
2173
|
+
this.#formBuilder = inject(FormBuilder);
|
|
2177
2174
|
// Signals States
|
|
2178
2175
|
this.lessonId = toSignal(inject(ActivatedRoute).paramMap.pipe(map((params) => params.get('id'))));
|
|
2179
|
-
this.lesson = signal(undefined
|
|
2180
|
-
this.isLoadingLesson = signal(false);
|
|
2176
|
+
this.lesson = signal(undefined, ...(ngDevMode ? [{ debugName: "lesson" }] : []));
|
|
2177
|
+
this.isLoadingLesson = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingLesson" }] : []));
|
|
2181
2178
|
// Computed Signals
|
|
2182
2179
|
this.coverImageUrl = computed(() => {
|
|
2183
2180
|
// Priority Order 1 Metadata Banner, 2 Banner, 3 Media First Images, 4 Default Banner TODO: reveme banner after migration to Content
|
|
2184
2181
|
const currentLesson = this.lesson();
|
|
2185
|
-
if (currentLesson?.
|
|
2186
|
-
return currentLesson.
|
|
2187
|
-
}
|
|
2188
|
-
else if (currentLesson?.banner?.url) {
|
|
2189
|
-
return currentLesson.banner.url;
|
|
2182
|
+
if (currentLesson?.assets?.banner?.url) {
|
|
2183
|
+
return currentLesson.assets.banner.url;
|
|
2190
2184
|
}
|
|
2191
2185
|
else if (currentLesson?.media?.images?.find((img) => img.type === 'cover')) {
|
|
2192
2186
|
// 3 Media First Images
|
|
2193
2187
|
return currentLesson.media.images.find((img) => img.type === 'cover')?.url;
|
|
2194
2188
|
}
|
|
2195
|
-
return '/assets/images/default_banner.webp';
|
|
2196
|
-
});
|
|
2189
|
+
return '/assets/defaults/images/default_banner.webp';
|
|
2190
|
+
}, ...(ngDevMode ? [{ debugName: "coverImageUrl" }] : []));
|
|
2197
2191
|
// Computed signal to get dynamic components as an array for easier iteration in the template
|
|
2198
2192
|
this.dynamicComponentsArray = computed(() => {
|
|
2199
2193
|
const currentLesson = this.lesson();
|
|
@@ -2201,7 +2195,7 @@ class DCLessonEditorComponent {
|
|
|
2201
2195
|
return Object.values(currentLesson.dynamicComponents);
|
|
2202
2196
|
}
|
|
2203
2197
|
return []; // Return empty array if no lesson or no dynamic components
|
|
2204
|
-
});
|
|
2198
|
+
}, ...(ngDevMode ? [{ debugName: "dynamicComponentsArray" }] : []));
|
|
2205
2199
|
// States
|
|
2206
2200
|
this.components = {}; // Current Dynamic components
|
|
2207
2201
|
this.editor = BalloonEditor;
|
|
@@ -2212,6 +2206,10 @@ class DCLessonEditorComponent {
|
|
|
2212
2206
|
cropSettings: { resizeToWidth: 850, aspectRatio: AspectType.RectangleLarge, resolutions: [ResolutionType.Medium] },
|
|
2213
2207
|
};
|
|
2214
2208
|
this.promptsVisible = false;
|
|
2209
|
+
this.lessonForm = this.#formBuilder.group({
|
|
2210
|
+
title: [''],
|
|
2211
|
+
description: [''],
|
|
2212
|
+
});
|
|
2215
2213
|
// Effect to fetch lesson data when ID changes
|
|
2216
2214
|
effect(async () => {
|
|
2217
2215
|
const id = this.lessonId();
|
|
@@ -2219,9 +2217,10 @@ class DCLessonEditorComponent {
|
|
|
2219
2217
|
if (id) {
|
|
2220
2218
|
this.isLoadingLesson.set(true); // Start loading
|
|
2221
2219
|
try {
|
|
2222
|
-
const fetchedLesson = await this
|
|
2220
|
+
const fetchedLesson = await this.lessonsService.getLesson(id);
|
|
2223
2221
|
if (fetchedLesson) {
|
|
2224
2222
|
this.lesson.set(fetchedLesson);
|
|
2223
|
+
this.lessonForm.patchValue(fetchedLesson, { emitEvent: false });
|
|
2225
2224
|
}
|
|
2226
2225
|
else {
|
|
2227
2226
|
this.lesson.set(undefined); // Reset if not found
|
|
@@ -2246,6 +2245,13 @@ class DCLessonEditorComponent {
|
|
|
2246
2245
|
this.isLoadingLesson.set(false); // Ensure loading is off
|
|
2247
2246
|
}
|
|
2248
2247
|
});
|
|
2248
|
+
this.lessonForm.valueChanges.subscribe((value) => {
|
|
2249
|
+
this.lesson.update((current) => {
|
|
2250
|
+
if (!current)
|
|
2251
|
+
return undefined;
|
|
2252
|
+
return { ...current, ...value };
|
|
2253
|
+
});
|
|
2254
|
+
});
|
|
2249
2255
|
}
|
|
2250
2256
|
/**
|
|
2251
2257
|
* Updates a specific property on the lesson signal.
|
|
@@ -2261,6 +2267,13 @@ class DCLessonEditorComponent {
|
|
|
2261
2267
|
return { ...currentLesson, [property]: value };
|
|
2262
2268
|
});
|
|
2263
2269
|
}
|
|
2270
|
+
onAssetsChange(updatedAssets) {
|
|
2271
|
+
this.lesson.update((currentLesson) => {
|
|
2272
|
+
if (!currentLesson)
|
|
2273
|
+
return undefined;
|
|
2274
|
+
return { ...currentLesson, assets: updatedAssets };
|
|
2275
|
+
});
|
|
2276
|
+
}
|
|
2264
2277
|
onTagRemove(tag) {
|
|
2265
2278
|
this.lesson.update((currentLesson) => {
|
|
2266
2279
|
if (!currentLesson)
|
|
@@ -2298,7 +2311,7 @@ class DCLessonEditorComponent {
|
|
|
2298
2311
|
this.isLoadingLesson.set(true); // Indicate saving
|
|
2299
2312
|
try {
|
|
2300
2313
|
// Use the cleaned lesson object for saving
|
|
2301
|
-
const savedLesson = await this
|
|
2314
|
+
const savedLesson = await this.lessonsService.postLesson(lessonToSave);
|
|
2302
2315
|
const currentId = this.lessonId();
|
|
2303
2316
|
if (!currentId) {
|
|
2304
2317
|
// No se como guardar los extras aunt
|
|
@@ -2397,7 +2410,7 @@ class DCLessonEditorComponent {
|
|
|
2397
2410
|
}
|
|
2398
2411
|
async generateBanner() {
|
|
2399
2412
|
this.#toastService.info({ title: 'Generando prompt de sugerencia', subtitle: 'Por favor, espera' });
|
|
2400
|
-
const prompt = this
|
|
2413
|
+
const prompt = this.lessonsService.getPrompts().banner(this.lesson());
|
|
2401
2414
|
const geminiRes = await this.ngxVertexService.generateText([{ role: ChatRoleVertex.User, content: prompt }]);
|
|
2402
2415
|
this.promptService
|
|
2403
2416
|
.openPrompt({
|
|
@@ -2412,7 +2425,8 @@ class DCLessonEditorComponent {
|
|
|
2412
2425
|
this.#loadingBarService.showIndeterminate();
|
|
2413
2426
|
this.defaultLessonsService.generateBanner(promptResult, this.lessonId()).then((result) => {
|
|
2414
2427
|
if (result) {
|
|
2415
|
-
|
|
2428
|
+
alert('Revisar como actualizar el banner');
|
|
2429
|
+
// this.updateLessonProperty('banner', (result as any).banner);
|
|
2416
2430
|
}
|
|
2417
2431
|
this.#loadingBarService.successAndHide();
|
|
2418
2432
|
});
|
|
@@ -2430,7 +2444,7 @@ class DCLessonEditorComponent {
|
|
|
2430
2444
|
}
|
|
2431
2445
|
showPrompts() {
|
|
2432
2446
|
this.promptsVisible = true;
|
|
2433
|
-
const promptsFn = this
|
|
2447
|
+
const promptsFn = this.lessonsService.getPrompts();
|
|
2434
2448
|
this.prompts = { banner: promptsFn.banner(this.lesson()), content: promptsFn.content(this.lesson()), description: promptsFn.description(this.lesson()) };
|
|
2435
2449
|
console.log(this.prompts);
|
|
2436
2450
|
this.cdr.markForCheck();
|
|
@@ -2441,12 +2455,11 @@ class DCLessonEditorComponent {
|
|
|
2441
2455
|
this.onComponentAdded(result);
|
|
2442
2456
|
});
|
|
2443
2457
|
}
|
|
2444
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2445
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2446
|
-
|
|
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"] }] }); }
|
|
2458
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2459
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader [assets]=\"lesson()?.assets\" storagePath=\"lessons/{{ lesson()?.id }}\" (assetsChange)=\"onAssetsChange($event)\"></assets-loader>\n </div>\n <div class=\"p-col-4\">\n <h3>Learnable</h3>\n <dc-learnable-viewer [data]=\"lesson()?.learnable\"></dc-learnable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Auditable</h3>\n <dc-auditable-viewer [data]=\"lesson()?.auditable\"></dc-auditable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Manageable</h3>\n <dc-manageable-viewer [data]=\"lesson()?.manageable\"></dc-manageable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Reactions</h3>\n <dc-reactions-viewer [data]=\"lesson()?.reactions\"></dc-reactions-viewer>\n </div>\n\n <div class=\"p-col-4\">\n <h3>Extensions</h3>\n <dc-extensions-viewer [data]=\"lesson()?.extensions\"></dc-extensions-viewer>\n </div>\n</div>\n\n<!-- Lesson Metadata Editor -->\n<!-- <dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [lessonForm]=\"lessonForm\"\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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$4.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: 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: ReactiveFormsModule }, { kind: "ngmodule", type: SplitterModule }, { kind: "component", type: i5$1.Splitter, selector: "p-splitter", inputs: ["styleClass", "panelStyleClass", "panelStyle", "stateStorage", "stateKey", "layout", "gutterSize", "step", "minSizes", "panelSizes"], outputs: ["onResizeEnd", "onResizeStart"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "component", type: DCLessonComponentAdderComponent, selector: "dc-lesson-component-adder", outputs: ["componentAdded"] }, { kind: "ngmodule", type: // Add the metadata editor here
|
|
2460
|
+
DialogModule }, { kind: "component", type: i7.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "component", type: DcExtensionsViewerComponent, selector: "dc-extensions-viewer", inputs: ["data"] }, { kind: "component", type: DcLearnableViewerComponent, selector: "dc-learnable-viewer", inputs: ["data"] }, { kind: "component", type: DcAuditableViewerComponent, selector: "dc-auditable-viewer", inputs: ["data"] }, { kind: "component", type: DcManageableViewerComponent, selector: "dc-manageable-viewer", inputs: ["data"] }, { kind: "component", type: DcReactionsViewerComponent, selector: "dc-reactions-viewer", inputs: ["data"] }, { kind: "component", type: AssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }] }); }
|
|
2448
2461
|
}
|
|
2449
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2462
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCLessonEditorComponent, decorators: [{
|
|
2450
2463
|
type: Component,
|
|
2451
2464
|
args: [{ selector: 'dc-lesson-editor', standalone: true, imports: [
|
|
2452
2465
|
ButtonModule,
|
|
@@ -2455,12 +2468,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2455
2468
|
DCLessonRendererComponent,
|
|
2456
2469
|
FormsModule,
|
|
2457
2470
|
InputTextModule,
|
|
2471
|
+
ReactiveFormsModule,
|
|
2458
2472
|
SplitterModule,
|
|
2459
2473
|
TooltipModule,
|
|
2460
2474
|
DCLessonComponentAdderComponent, // Add the component adder here
|
|
2461
2475
|
DCLessonMetadataEditorComponent, // Add the metadata editor here
|
|
2462
2476
|
DialogModule,
|
|
2463
|
-
|
|
2477
|
+
DcExtensionsViewerComponent,
|
|
2478
|
+
DcLearnableViewerComponent,
|
|
2479
|
+
DcAuditableViewerComponent,
|
|
2480
|
+
DcManageableViewerComponent,
|
|
2481
|
+
DcReactionsViewerComponent,
|
|
2482
|
+
AssetsLoaderComponent,
|
|
2483
|
+
], 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<div class=\"p-grid\">\n <div class=\"p-col-4\">\n <assets-loader [assets]=\"lesson()?.assets\" storagePath=\"lessons/{{ lesson()?.id }}\" (assetsChange)=\"onAssetsChange($event)\"></assets-loader>\n </div>\n <div class=\"p-col-4\">\n <h3>Learnable</h3>\n <dc-learnable-viewer [data]=\"lesson()?.learnable\"></dc-learnable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Auditable</h3>\n <dc-auditable-viewer [data]=\"lesson()?.auditable\"></dc-auditable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Manageable</h3>\n <dc-manageable-viewer [data]=\"lesson()?.manageable\"></dc-manageable-viewer>\n </div>\n <div class=\"p-col-4\">\n <h3>Reactions</h3>\n <dc-reactions-viewer [data]=\"lesson()?.reactions\"></dc-reactions-viewer>\n </div>\n\n <div class=\"p-col-4\">\n <h3>Extensions</h3>\n <dc-extensions-viewer [data]=\"lesson()?.extensions\"></dc-extensions-viewer>\n </div>\n</div>\n\n<!-- Lesson Metadata Editor -->\n<!-- <dc-lesson-metadata-editor\n [lesson]=\"lesson\"\n [lessonForm]=\"lessonForm\"\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"] }]
|
|
2464
2484
|
}], ctorParameters: () => [], propDecorators: { target: [{
|
|
2465
2485
|
type: ViewChild,
|
|
2466
2486
|
args: ['target', { read: ViewContainerRef }]
|
|
@@ -2474,10 +2494,10 @@ class LessonDynamicComponent {
|
|
|
2474
2494
|
constructor() {
|
|
2475
2495
|
this.settings = {};
|
|
2476
2496
|
}
|
|
2477
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2478
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2497
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonDynamicComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2498
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: LessonDynamicComponent, isStandalone: true, selector: "app-lesson-component", inputs: { settings: "settings" }, ngImport: i0, template: '<div>no template</div>', isInline: true }); }
|
|
2479
2499
|
}
|
|
2480
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2500
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: LessonDynamicComponent, decorators: [{
|
|
2481
2501
|
type: Component,
|
|
2482
2502
|
args: [{
|
|
2483
2503
|
selector: 'app-lesson-component',
|
|
@@ -2488,7 +2508,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2488
2508
|
type: Input
|
|
2489
2509
|
}] } });
|
|
2490
2510
|
|
|
2491
|
-
const Endpoints
|
|
2511
|
+
const Endpoints = {
|
|
2492
2512
|
courses: 'api/courses',
|
|
2493
2513
|
};
|
|
2494
2514
|
class CoursesService {
|
|
@@ -2497,12 +2517,12 @@ class CoursesService {
|
|
|
2497
2517
|
}
|
|
2498
2518
|
// Not sure how to implement this yet.
|
|
2499
2519
|
getCourses() {
|
|
2500
|
-
return this.httpCoreService.get(Endpoints
|
|
2520
|
+
return this.httpCoreService.get(Endpoints.courses);
|
|
2501
2521
|
}
|
|
2502
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2503
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2522
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2523
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesService, providedIn: 'root' }); }
|
|
2504
2524
|
}
|
|
2505
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2525
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesService, decorators: [{
|
|
2506
2526
|
type: Injectable,
|
|
2507
2527
|
args: [{
|
|
2508
2528
|
providedIn: 'root',
|
|
@@ -2517,92 +2537,41 @@ class CoursesAdminComponent {
|
|
|
2517
2537
|
const courses = await this.httpCoreService.get('courses');
|
|
2518
2538
|
console.log(courses);
|
|
2519
2539
|
}
|
|
2520
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2521
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesAdminComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2541
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: CoursesAdminComponent, isStandalone: true, selector: "ngx-courses-admin", ngImport: i0, template: "<p>welcome to courses creation</p>\n", styles: [""] }); }
|
|
2522
2542
|
}
|
|
2523
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesAdminComponent, decorators: [{
|
|
2524
2544
|
type: Component,
|
|
2525
2545
|
args: [{ selector: 'ngx-courses-admin', standalone: true, template: "<p>welcome to courses creation</p>\n" }]
|
|
2526
2546
|
}] });
|
|
2527
2547
|
|
|
2528
|
-
class
|
|
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 {
|
|
2548
|
+
class CourseService extends EntityCommunicationService {
|
|
2555
2549
|
constructor() {
|
|
2556
|
-
|
|
2557
|
-
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2550
|
+
super('courses');
|
|
2558
2551
|
}
|
|
2559
|
-
|
|
2560
|
-
|
|
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' }); }
|
|
2552
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2553
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseService, providedIn: 'root' }); }
|
|
2585
2554
|
}
|
|
2586
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2555
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseService, decorators: [{
|
|
2587
2556
|
type: Injectable,
|
|
2588
2557
|
args: [{
|
|
2589
2558
|
providedIn: 'root',
|
|
2590
2559
|
}]
|
|
2591
|
-
}] });
|
|
2560
|
+
}], ctorParameters: () => [] });
|
|
2592
2561
|
|
|
2593
2562
|
class CourseListComponent extends PaginationBase {
|
|
2594
2563
|
constructor() {
|
|
2595
2564
|
super(...arguments);
|
|
2596
2565
|
// Services
|
|
2597
2566
|
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
2598
|
-
this.
|
|
2567
|
+
this.courseService = inject(CourseService);
|
|
2599
2568
|
this.cdr = inject(ChangeDetectorRef);
|
|
2600
2569
|
// Inputs
|
|
2601
2570
|
this.viewType = 'card';
|
|
2602
|
-
this.onlyView = input(true);
|
|
2571
|
+
this.onlyView = input(true, ...(ngDevMode ? [{ debugName: "onlyView" }] : []));
|
|
2603
2572
|
this.onSelect = output();
|
|
2604
2573
|
// States
|
|
2605
|
-
this.courses = signal([]);
|
|
2574
|
+
this.courses = signal([], ...(ngDevMode ? [{ debugName: "courses" }] : []));
|
|
2606
2575
|
this.columns = ['name', 'description', 'updatedAt', 'image'];
|
|
2607
2576
|
this.filterBarOptions = { showActions: true, showCreateButton: true, showViewButton: true };
|
|
2608
2577
|
}
|
|
@@ -2627,7 +2596,8 @@ class CourseListComponent extends PaginationBase {
|
|
|
2627
2596
|
}
|
|
2628
2597
|
async ngOnInit() {
|
|
2629
2598
|
this.filterConfig.returnProps = { _id: 1, id: 1, name: 1, description: 1, updatedAt: 1, image: 1 };
|
|
2630
|
-
|
|
2599
|
+
this.filterConfig.filters = { targetLang: 'de', baseLang: 'es' };
|
|
2600
|
+
const response = await this.courseService.query(this.filterConfig);
|
|
2631
2601
|
this.courses.set(response.rows);
|
|
2632
2602
|
this.cdr.detectChanges();
|
|
2633
2603
|
console.log(this.courses(), this.viewType);
|
|
@@ -2654,15 +2624,15 @@ class CourseListComponent extends PaginationBase {
|
|
|
2654
2624
|
if (action == 'changeView') {
|
|
2655
2625
|
this.toggleView();
|
|
2656
2626
|
}
|
|
2627
|
+
const id = item.id || item._id;
|
|
2657
2628
|
switch (action) {
|
|
2658
2629
|
case 'view':
|
|
2659
|
-
this.router.navigate(['./details',
|
|
2630
|
+
this.router.navigate(['./details', id], { relativeTo: this.route });
|
|
2660
2631
|
break;
|
|
2661
2632
|
case 'delete':
|
|
2662
2633
|
const areYouSure = confirm('¿Estás seguro de querer eliminar este origen?');
|
|
2663
2634
|
if (areYouSure) {
|
|
2664
|
-
|
|
2665
|
-
await this.sourceService.deleteCourse(id);
|
|
2635
|
+
await this.courseService.remove(id);
|
|
2666
2636
|
this.courses.set(this.courses().filter((course) => course._id !== id));
|
|
2667
2637
|
this.toastService.success({
|
|
2668
2638
|
title: 'Origen eliminado',
|
|
@@ -2672,14 +2642,14 @@ class CourseListComponent extends PaginationBase {
|
|
|
2672
2642
|
}
|
|
2673
2643
|
break;
|
|
2674
2644
|
case 'edit':
|
|
2675
|
-
this.router.navigate(['./edit',
|
|
2645
|
+
this.router.navigate(['./edit', id], { relativeTo: this.route });
|
|
2676
2646
|
break;
|
|
2677
2647
|
}
|
|
2678
2648
|
}
|
|
2679
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2680
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2649
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2650
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 [tooltipOptions]=\"{ tooltipPosition: 'top' }\" />\n\n />\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 [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", "buttonProps", "autofocus", "fluid"], 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: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$2.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2681
2651
|
}
|
|
2682
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2652
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseListComponent, decorators: [{
|
|
2683
2653
|
type: Component,
|
|
2684
2654
|
args: [{ selector: 'app-course-list', imports: [
|
|
2685
2655
|
CardModule,
|
|
@@ -2692,19 +2662,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2692
2662
|
RouterModule,
|
|
2693
2663
|
TableModule,
|
|
2694
2664
|
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 [
|
|
2665
|
+
], 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 [tooltipOptions]=\"{ tooltipPosition: 'top' }\" />\n\n />\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 [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
2666
|
}], propDecorators: { viewType: [{
|
|
2697
2667
|
type: Input
|
|
2698
2668
|
}] } });
|
|
2699
2669
|
|
|
2700
|
-
class
|
|
2670
|
+
class CourseDetailComponent {
|
|
2671
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2672
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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 }); }
|
|
2673
|
+
}
|
|
2674
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseDetailComponent, decorators: [{
|
|
2675
|
+
type: Component,
|
|
2676
|
+
args: [{ selector: 'app-course-detail', imports: [], template: `<p>course-detail works!</p>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
|
|
2677
|
+
}] });
|
|
2678
|
+
|
|
2679
|
+
class CourseFormComponent extends EntityBaseFormComponent {
|
|
2701
2680
|
constructor() {
|
|
2702
|
-
|
|
2703
|
-
this.
|
|
2681
|
+
super(...arguments);
|
|
2682
|
+
this.entityCommunicationService = inject(CourseService);
|
|
2704
2683
|
this.fb = inject(FormBuilder);
|
|
2705
|
-
this.
|
|
2706
|
-
this.
|
|
2707
|
-
|
|
2684
|
+
this.languageOptions = getSupportedLanguageOptions('en');
|
|
2685
|
+
this.form = this.fb.group({
|
|
2686
|
+
name: ['', Validators.required],
|
|
2687
|
+
description: [''],
|
|
2688
|
+
image: [{}],
|
|
2689
|
+
targetLang: ['', Validators.required],
|
|
2690
|
+
baseLang: ['', Validators.required],
|
|
2691
|
+
});
|
|
2692
|
+
this.onSave = output();
|
|
2708
2693
|
this.storageImgSettings = {
|
|
2709
2694
|
path: `courses`,
|
|
2710
2695
|
cropSettings: { aspectRatio: AspectType.Square, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 700 },
|
|
@@ -2713,46 +2698,32 @@ class CourseFormComponent {
|
|
|
2713
2698
|
{ key: 'title', type: 'input', props: { label: 'Title', placeholder: 'Title', required: false } },
|
|
2714
2699
|
{ key: 'content', type: 'textarea', props: { label: 'Content', placeholder: 'Content', required: false } },
|
|
2715
2700
|
];
|
|
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
2701
|
}
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
this.course = await this.courseService.getCourse(this.courseId);
|
|
2727
|
-
if (this.course) {
|
|
2728
|
-
this.courseForm.patchValue(this.course);
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2702
|
+
patchForm(entity) {
|
|
2703
|
+
this.form.patchValue(entity);
|
|
2731
2704
|
}
|
|
2732
2705
|
async save() {
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
if (
|
|
2737
|
-
this.
|
|
2706
|
+
const result = await super.save();
|
|
2707
|
+
if (result) {
|
|
2708
|
+
this.onSave.emit(result);
|
|
2709
|
+
if (this.toastService) {
|
|
2710
|
+
this.toastService.success({ title: 'Course', subtitle: 'Data was saved' });
|
|
2738
2711
|
}
|
|
2739
|
-
this.toastService.success({ title: 'Origen guardado', subtitle: 'El origen ha sido guardado correctamente' });
|
|
2740
2712
|
}
|
|
2713
|
+
return result;
|
|
2741
2714
|
}
|
|
2742
2715
|
handleImageUpload(event) {
|
|
2743
|
-
|
|
2744
|
-
alert('Image uploaded');
|
|
2716
|
+
this.form.patchValue({ image: event });
|
|
2745
2717
|
}
|
|
2746
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2747
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "
|
|
2718
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2719
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: CourseFormComponent, isStandalone: true, selector: "app-source-form", outputs: { onSave: "onSave" }, usesInheritance: true, ngImport: i0, template: "<h3>Courses Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"entityId() ? 'Edit Course' : 'New Course'\">\n <form [formGroup]=\"form\">\n <div class=\"form-field\">\n <label for=\"baseLang\">Base Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"baseLang\"\n [options]=\"languageOptions\"\n [filter]=\"true\"\n formControlName=\"baseLang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label for=\"targetLang\">Target Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"targetLang\"\n [filter]=\"true\"\n [options]=\"languageOptions\"\n formControlName=\"targetLang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\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]=\"!form.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], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i2.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "component", type: 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
2720
|
}
|
|
2749
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2721
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CourseFormComponent, decorators: [{
|
|
2750
2722
|
type: Component,
|
|
2751
2723
|
args: [{ selector: 'app-source-form', imports: [
|
|
2752
2724
|
ReactiveFormsModule,
|
|
2753
2725
|
CardModule,
|
|
2754
2726
|
TextareaModule,
|
|
2755
|
-
DropdownModule,
|
|
2756
2727
|
ButtonModule,
|
|
2757
2728
|
SelectModule,
|
|
2758
2729
|
InputTextModule,
|
|
@@ -2762,7 +2733,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2762
2733
|
FormlyModule,
|
|
2763
2734
|
DialogModule,
|
|
2764
2735
|
CourseListComponent,
|
|
2765
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<h3>Courses Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"
|
|
2736
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<h3>Courses Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"entityId() ? 'Edit Course' : 'New Course'\">\n <form [formGroup]=\"form\">\n <div class=\"form-field\">\n <label for=\"baseLang\">Base Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"baseLang\"\n [options]=\"languageOptions\"\n [filter]=\"true\"\n formControlName=\"baseLang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label for=\"targetLang\">Target Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"targetLang\"\n [filter]=\"true\"\n [options]=\"languageOptions\"\n formControlName=\"targetLang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\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]=\"!form.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"] }]
|
|
2737
|
+
}] });
|
|
2738
|
+
|
|
2739
|
+
const COURSES_ROUTES = [
|
|
2740
|
+
{
|
|
2741
|
+
path: '',
|
|
2742
|
+
component: CoursesComponent,
|
|
2743
|
+
children: [
|
|
2744
|
+
{
|
|
2745
|
+
path: '',
|
|
2746
|
+
component: CourseListComponent,
|
|
2747
|
+
},
|
|
2748
|
+
{
|
|
2749
|
+
path: 'details/:id',
|
|
2750
|
+
component: CourseDetailComponent,
|
|
2751
|
+
},
|
|
2752
|
+
{
|
|
2753
|
+
path: 'edit',
|
|
2754
|
+
component: CourseFormComponent,
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
path: 'edit/:id',
|
|
2758
|
+
component: CourseFormComponent,
|
|
2759
|
+
},
|
|
2760
|
+
],
|
|
2761
|
+
},
|
|
2762
|
+
];
|
|
2763
|
+
|
|
2764
|
+
class CoursesComponent {
|
|
2765
|
+
static { this.routes = COURSES_ROUTES; }
|
|
2766
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2767
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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 }); }
|
|
2768
|
+
}
|
|
2769
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CoursesComponent, decorators: [{
|
|
2770
|
+
type: Component,
|
|
2771
|
+
args: [{ selector: 'app-courses', imports: [RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<router-outlet />\n", styles: [":host{display:block;height:100%}\n"] }]
|
|
2766
2772
|
}] });
|
|
2767
2773
|
|
|
2768
2774
|
/*
|
|
@@ -2773,5 +2779,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2773
2779
|
* Generated bundle index. Do not edit.
|
|
2774
2780
|
*/
|
|
2775
2781
|
|
|
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,
|
|
2782
|
+
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, NOTION_SERVICE_TOKEN, NotionAbstractService, NotionExportType, SelectorBuilderComponent, SelectorComponent, TextWriterBuiderComponent, TextWriterComponent, TranslationSwitcherBuilderComponent, TranslationSwitcherComponent, getLanguageSimpleAgent, getLessonComponentClass, provideLessonsService, provideNotionService };
|
|
2777
2783
|
//# sourceMappingURL=dataclouder-ngx-lessons.mjs.map
|