@rolatech/angular-course 17.3.1 → 17.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/esm2022/index.mjs +2 -1
  2. package/esm2022/lib/components/schedule-item/schedule-item.component.mjs +4 -4
  3. package/esm2022/lib/pages/course-manage/course-manage-content/course-manage-content.component.mjs +12 -0
  4. package/esm2022/lib/pages/course-manage/course-manage-details/course-manage-details.component.mjs +159 -0
  5. package/esm2022/lib/pages/course-manage/course-manage-info/course-manage-info.component.mjs +139 -0
  6. package/esm2022/lib/pages/course-manage/course-manage-layout/course-manage-layout.component.mjs +68 -0
  7. package/esm2022/lib/pages/course-manage/course-manage-media/course-manage-media.component.mjs +137 -0
  8. package/esm2022/lib/pages/course-manage/course-manage-pricing/course-manage-pricing.component.mjs +126 -0
  9. package/esm2022/lib/pages/course-manage/course-manage-schedule/course-manage-schedule.component.mjs +126 -0
  10. package/esm2022/lib/pages/course-manage/course-manage-section/course-manage-section.component.mjs +342 -0
  11. package/esm2022/lib/pages/course-manage/course-manage.routes.mjs +40 -0
  12. package/esm2022/lib/services/booking.service.mjs +24 -0
  13. package/esm2022/lib/services/instructor.service.mjs +24 -0
  14. package/fesm2022/{rolatech-angular-course-course-index.component-Bm6Sg8zH.mjs → rolatech-angular-course-course-index.component-BiS-U0WO.mjs} +5 -4
  15. package/fesm2022/{rolatech-angular-course-course-index.component-Bm6Sg8zH.mjs.map → rolatech-angular-course-course-index.component-BiS-U0WO.mjs.map} +1 -1
  16. package/fesm2022/{rolatech-angular-course-rolatech-angular-course-D-_W2GtF.mjs → rolatech-angular-course-rolatech-angular-course-DhmJ0teX.mjs} +1098 -16
  17. package/fesm2022/rolatech-angular-course-rolatech-angular-course-DhmJ0teX.mjs.map +1 -0
  18. package/fesm2022/rolatech-angular-course.mjs +2 -1
  19. package/fesm2022/rolatech-angular-course.mjs.map +1 -1
  20. package/index.d.ts +1 -0
  21. package/lib/components/schedule-item/schedule-item.component.d.ts +1 -1
  22. package/lib/pages/course-manage/course-manage-content/course-manage-content.component.d.ts +5 -0
  23. package/lib/pages/course-manage/course-manage-details/course-manage-details.component.d.ts +29 -0
  24. package/lib/pages/course-manage/course-manage-info/course-manage-info.component.d.ts +36 -0
  25. package/lib/pages/course-manage/course-manage-layout/course-manage-layout.component.d.ts +26 -0
  26. package/lib/pages/course-manage/course-manage-media/course-manage-media.component.d.ts +29 -0
  27. package/lib/pages/course-manage/course-manage-pricing/course-manage-pricing.component.d.ts +27 -0
  28. package/lib/pages/course-manage/course-manage-schedule/course-manage-schedule.component.d.ts +27 -0
  29. package/lib/pages/course-manage/course-manage-section/course-manage-section.component.d.ts +37 -0
  30. package/lib/pages/course-manage/course-manage.routes.d.ts +2 -0
  31. package/lib/services/booking.service.d.ts +9 -0
  32. package/lib/services/instructor.service.d.ts +9 -0
  33. package/package.json +1 -1
  34. package/themes/_default.scss +1 -1
  35. package/fesm2022/rolatech-angular-course-rolatech-angular-course-D-_W2GtF.mjs.map +0 -1
@@ -4,13 +4,13 @@ import * as i6 from '@angular/forms';
4
4
  import { ReactiveFormsModule, FormsModule } from '@angular/forms';
5
5
  import { CommonModule, NgClass, DatePipe, isPlatformBrowser, ViewportScroller } from '@angular/common';
6
6
  import * as i1$3 from '@angular/router';
7
- import { RouterModule, RouterLink, ActivatedRoute, Router } from '@angular/router';
7
+ import { RouterModule, RouterLink, ActivatedRoute, Router, RouterLinkActive, RouterOutlet } from '@angular/router';
8
8
  import { BaseService, DialogService } from '@rolatech/angular-services';
9
9
  import * as i2 from '@angular/material/icon';
10
10
  import { MatIconModule } from '@angular/material/icon';
11
11
  import * as i1$2 from '@angular/material/dialog';
12
12
  import { MatDialog, MAT_DIALOG_DATA, MatDialogClose } from '@angular/material/dialog';
13
- import { ImagePreviewDialogComponent, ThumbnailComponent, IconButtonComponent, AngularComponentsModule, ImageComponent, MediaListComponent, MediaListItemComponent, BaseComponent, AppContainerComponent, ListComponent } from '@rolatech/angular-components';
13
+ import { ImagePreviewDialogComponent, ThumbnailComponent, IconButtonComponent, AngularComponentsModule, ImageComponent, MediaListComponent, MediaListItemComponent, BaseComponent, AppContainerComponent, ListComponent, ConfirmationDialogComponent, ToolbarComponent } from '@rolatech/angular-components';
14
14
  import * as i3 from '@angular/material/button';
15
15
  import { MatButtonModule } from '@angular/material/button';
16
16
  import * as i1 from '@angular/material/expansion';
@@ -20,10 +20,10 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
20
20
  import { DurationPipe, AngularCommonModule } from '@rolatech/angular-common';
21
21
  import * as i5$1 from '@angular/material/divider';
22
22
  import { MatDividerModule } from '@angular/material/divider';
23
- import * as i7$1 from '@angular/material/stepper';
23
+ import * as i7 from '@angular/material/stepper';
24
24
  import { MatStepperModule, MatStepper } from '@angular/material/stepper';
25
25
  import { MomentDateAdapter } from '@angular/material-moment-adapter';
26
- import * as i7 from '@angular/material/core';
26
+ import * as i6$2 from '@angular/material/core';
27
27
  import { DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS, MatOptionModule } from '@angular/material/core';
28
28
  import moment from 'moment';
29
29
  import * as i6$1 from '@angular/material/select';
@@ -40,9 +40,10 @@ import * as i3$3 from '@angular/material/snack-bar';
40
40
  import { MatSnackBar } from '@angular/material/snack-bar';
41
41
  import * as i4 from '@angular/material/progress-bar';
42
42
  import { MatProgressBarModule } from '@angular/material/progress-bar';
43
- import { first, remove, findLastIndex } from 'lodash';
43
+ import { first, remove, findLastIndex, findIndex, clone } from 'lodash';
44
44
  import { AuthService, AuthUserService } from '@rolatech/angular-auth';
45
45
  import { CommentsComponent } from '@rolatech/angular-comment';
46
+ import { Observable, from, concatMap, take } from 'rxjs';
46
47
 
47
48
  var CourseStatus;
48
49
  (function (CourseStatus) {
@@ -709,7 +710,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
709
710
  args: [{ selector: 'rolatech-course-section-item', standalone: true, imports: [MatIconModule, FormsModule, MatButtonModule, IconButtonComponent], template: "<div class=\"flex flex-col grow\">\n @if (section().id !== editId()) {\n <div>\n <div class=\"flex justify-between items-center cursor-pointer\" (click)=\"isExpand = !isExpand\">\n <div class=\"w-full flex items-center gap-3 pl-3\">\n <span>{{ section().title }}</span>\n <button mat-icon-button class=\"max-w-8 max-h-8 !p-1\" (click)=\"onEdit(section())\">\n <mat-icon>edit</mat-icon>\n </button>\n <button mat-icon-button class=\"max-w-8 max-h-8 !p-1\" (click)=\"onDelete(section())\">\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n <!-- <rolatech-icon-button (click)=\"isExpand = !isExpand\">{{\n isExpand ? 'expand_less' : 'expand_more'\n }}</rolatech-icon-button> -->\n <button mat-icon-button class=\"max-w-8 max-h-8 !p-1\">\n <mat-icon>{{ isExpand ? 'expand_less' : 'expand_more' }}</mat-icon>\n </button>\n </div>\n @if (isExpand) {\n <div>\n <ng-content></ng-content>\n </div>\n }\n </div>\n } @else {\n <div class=\"flex flex-col justify-between items-center\">\n <input\n type=\"text\"\n class=\"bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-md focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\"\n placeholder=\"\u6807\u9898\"\n [(ngModel)]=\"section().title\"\n />\n <div class=\"w-full flex flex-row justify-end p-4 gap-3\">\n <button mat-button (click)=\"onCancel(section())\">\u53D6\u6D88</button>\n <button mat-flat-button color=\"primary\" (click)=\"onSave(section())\">\u4FDD\u5B58</button>\n </div>\n </div>\n }\n <!-- <mat-form-field appearance=\"fill\">\n <mat-label>\u63CF\u8FF0</mat-label>\n <input matInput placeholder=\"\u63CF\u8FF0\" [(ngModel)]=\"section.description\" />\n </mat-form-field> -->\n</div>\n" }]
710
711
  }] });
711
712
 
712
- const MY_FORMATS = {
713
+ const COURSE_SCHEDULE_DATE_FORMATS = {
713
714
  parse: {
714
715
  dateInput: 'YYYY-MM-DD',
715
716
  },
@@ -780,9 +781,9 @@ class ScheduleItemComponent {
780
781
  useClass: MomentDateAdapter,
781
782
  deps: [MAT_DATE_LOCALE],
782
783
  },
783
- { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
784
+ { provide: MAT_DATE_FORMATS, useValue: COURSE_SCHEDULE_DATE_FORMATS },
784
785
  DatePipe,
785
- ], ngImport: i0, template: "<div class=\"flex flex-col py-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u6807\u9898 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"schedule.title\" name=\"title\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u5185\u5BB9 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"schedule.content\"\n name=\"content\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n required\n ></textarea>\n </mat-form-field>\n <div class=\"flex flex-row gap-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label>\u5F00\u59CB\u65E5\u671F</mat-label>\n <input\n matInput\n [matDatepicker]=\"picker\"\n (focus)=\"picker.open()\"\n name=\"startAt\"\n [(ngModel)]=\"schedule.startDate\"\n (ngModelChange)=\"startDateChanged($event)\"\n (dateInput)=\"schedule.startDate = $event.value.format('YYYY-MM-DD')\"\n readonly\n required\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u5F00\u59CB\u65F6\u95F4</mat-label>\n <mat-select [(ngModel)]=\"schedule.startTime\" (selectionChange)=\"startTimeChanged($event)\" required readonly>\n @for (d of date; track d) {\n <mat-option [value]=\"d\">\n {{ d }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"flex flex-row gap-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7ED3\u675F\u65E5\u671F</mat-label>\n <input\n matInput\n [matDatepicker]=\"picker2\"\n name=\"endAt\"\n (focus)=\"picker2.open()\"\n (ngModelChange)=\"endDateChanged($event)\"\n [(ngModel)]=\"schedule.endDate\"\n (dateInput)=\"schedule.endDate = $event.value.format('YYYY-MM-DD')\"\n readonly\n required\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker #picker2></mat-datepicker>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7ED3\u675F\u65F6\u95F4</mat-label>\n <mat-select [(ngModel)]=\"schedule.endTime\" (selectionChange)=\"endTimeChanged($event)\" required readonly>\n @for (d of date; track d) {\n <mat-option [value]=\"d\">\n {{ d }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n</div>\n@if (actions()) {\n <div class=\"flex flex-row justify-end p-4\">\n <button mat-button (click)=\"onDelete(schedule)\">\u5220\u9664</button>\n <button mat-button (click)=\"onSave(schedule)\">\u4FDD\u5B58</button>\n </div>\n}\n<mat-divider></mat-divider>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] }); }
786
+ ], ngImport: i0, template: "<div class=\"flex flex-col py-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u6807\u9898 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"schedule.title\" name=\"title\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u5185\u5BB9 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"schedule.content\"\n name=\"content\"\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n required\n ></textarea>\n </mat-form-field>\n <div class=\"flex flex-row gap-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label>\u5F00\u59CB\u65E5\u671F</mat-label>\n <input\n matInput\n [matDatepicker]=\"picker\"\n (focus)=\"picker.open()\"\n name=\"startAt\"\n [(ngModel)]=\"schedule.startDate\"\n (ngModelChange)=\"startDateChanged($event)\"\n (dateInput)=\"schedule.startDate = $event.value.format('YYYY-MM-DD')\"\n readonly\n required\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u5F00\u59CB\u65F6\u95F4</mat-label>\n <mat-select [(ngModel)]=\"schedule.startTime\" (selectionChange)=\"startTimeChanged($event)\" required readonly>\n @for (d of date; track d) {\n <mat-option [value]=\"d\">\n {{ d }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"flex flex-row gap-3\">\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7ED3\u675F\u65E5\u671F</mat-label>\n <input\n matInput\n [matDatepicker]=\"picker2\"\n name=\"endAt\"\n (focus)=\"picker2.open()\"\n (ngModelChange)=\"endDateChanged($event)\"\n [(ngModel)]=\"schedule.endDate\"\n (dateInput)=\"schedule.endDate = $event.value.format('YYYY-MM-DD')\"\n readonly\n required\n />\n <mat-datepicker-toggle matIconSuffix [for]=\"picker2\"></mat-datepicker-toggle>\n <mat-datepicker #picker2></mat-datepicker>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7ED3\u675F\u65F6\u95F4</mat-label>\n <mat-select [(ngModel)]=\"schedule.endTime\" (selectionChange)=\"endTimeChanged($event)\" required readonly>\n @for (d of date; track d) {\n <mat-option [value]=\"d\">\n {{ d }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </div>\n</div>\n@if (actions()) {\n <div class=\"flex flex-row justify-end p-4\">\n <button mat-button (click)=\"onDelete(schedule)\">\u5220\u9664</button>\n <button mat-button (click)=\"onSave(schedule)\">\u4FDD\u5B58</button>\n </div>\n}\n<mat-divider></mat-divider>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i5.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i5.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i5.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }] }); }
786
787
  }
787
788
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ScheduleItemComponent, decorators: [{
788
789
  type: Component,
@@ -792,7 +793,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
792
793
  useClass: MomentDateAdapter,
793
794
  deps: [MAT_DATE_LOCALE],
794
795
  },
795
- { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
796
+ { provide: MAT_DATE_FORMATS, useValue: COURSE_SCHEDULE_DATE_FORMATS },
796
797
  DatePipe,
797
798
  ], standalone: true, imports: [
798
799
  NgClass,
@@ -1134,7 +1135,7 @@ class CoursePricingDialogComponent {
1134
1135
  });
1135
1136
  }
1136
1137
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CoursePricingDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: CourseService }, { token: i3$3.MatSnackBar }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
1137
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CoursePricingDialogComponent, isStandalone: true, selector: "rolatech-course-pricing-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto w-2/3 max-h-[55vh]\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of pricing; track item) {\n <rolatech-pricing-item [pricing]=\"item\"> </rolatech-pricing-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addPricing()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"pricing\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7$1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: PricingItemComponent, selector: "rolatech-pricing-item", inputs: ["actions", "pricing"], outputs: ["pricingChange", "delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1138
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CoursePricingDialogComponent, isStandalone: true, selector: "rolatech-course-pricing-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto w-2/3 max-h-[55vh]\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of pricing; track item) {\n <rolatech-pricing-item [pricing]=\"item\"> </rolatech-pricing-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addPricing()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"pricing\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: PricingItemComponent, selector: "rolatech-pricing-item", inputs: ["actions", "pricing"], outputs: ["pricingChange", "delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1138
1139
  }
1139
1140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CoursePricingDialogComponent, decorators: [{
1140
1141
  type: Component,
@@ -1178,7 +1179,7 @@ class CourseScheduleDialogComponent {
1178
1179
  });
1179
1180
  }
1180
1181
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseScheduleDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: CourseService }, { token: i3$3.MatSnackBar }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
1181
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseScheduleDialogComponent, isStandalone: true, selector: "rolatech-course-schedule-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of schedule; track item) {\n <rolatech-schedule-item [value]=\"item\"></rolatech-schedule-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addSchedule()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"schedule\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7$1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: ScheduleItemComponent, selector: "rolatech-schedule-item", inputs: ["value", "actions"], outputs: ["delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1182
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseScheduleDialogComponent, isStandalone: true, selector: "rolatech-course-schedule-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of schedule; track item) {\n <rolatech-schedule-item [value]=\"item\"></rolatech-schedule-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addSchedule()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"schedule\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: ScheduleItemComponent, selector: "rolatech-schedule-item", inputs: ["value", "actions"], outputs: ["delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1182
1183
  }
1183
1184
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseScheduleDialogComponent, decorators: [{
1184
1185
  type: Component,
@@ -1302,7 +1303,7 @@ class CourseDetailsDialogComponent {
1302
1303
  });
1303
1304
  }
1304
1305
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseDetailsDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: CourseService }, { token: i3$3.MatSnackBar }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
1305
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseDetailsDialogComponent, isStandalone: true, selector: "rolatech-course-details-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of details; track item) {\n <rolatech-detail-item\n [detail]=\"item\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n ></rolatech-detail-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addDetail()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"true\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7$1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: DetailItemComponent, selector: "rolatech-detail-item", inputs: ["isUploading", "detail", "actions", "selectMedia"], outputs: ["upload", "delete", "save", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1306
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseDetailsDialogComponent, isStandalone: true, selector: "rolatech-course-details-dialog", ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <form #detailForm=\"ngForm\" class=\"p-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of details; track item) {\n <rolatech-detail-item\n [detail]=\"item\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n ></rolatech-detail-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addDetail()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n </form>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n <button mat-button [mat-dialog-close]=\"true\" cdkFocusInitial>\u4FDD\u5B58</button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "directive", type: i7.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: DetailItemComponent, selector: "rolatech-detail-item", inputs: ["isUploading", "detail", "actions", "selectMedia"], outputs: ["upload", "delete", "save", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1306
1307
  }
1307
1308
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseDetailsDialogComponent, decorators: [{
1308
1309
  type: Component,
@@ -1492,7 +1493,7 @@ class CourseEditDialogComponent {
1492
1493
  }
1493
1494
  }
1494
1495
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseEditDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: CategoryService }, { token: CourseService }, { token: i3$3.MatSnackBar }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
1495
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseEditDialogComponent, isStandalone: true, selector: "rolatech-course-edit-dialog", viewQueries: [{ propertyName: "stepper", first: true, predicate: MatStepper, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <mat-stepper #stepper (selectionChange)=\"onStepperChange($event)\">\n <mat-step [editable]=\"true\">\n <form #infoForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u57FA\u672C\u4FE1\u606F</ng-template>\n <div class=\"flex flex-col\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u540D\u79F0 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"course.name\" name=\"name\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u63CF\u8FF0 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"course.description\"\n name=\"description\"\n required\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" ngModelGroup=\"categories\">\n <mat-label>\u5206\u7C7B</mat-label>\n <mat-select\n multiple\n name=\"id\"\n [compareWith]=\"compareFn\"\n [(ngModel)]=\"course.categories\"\n #select=\"matSelect\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n @for (item of categories; track item) {\n <mat-option [value]=\"item\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7C7B\u578B</mat-label>\n <mat-select name=\"type\" [(ngModel)]=\"course.type\">\n @for (item of courseType; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (course.type.toString() !== 'ONLINE') {\n <mat-form-field appearance=\"fill\" ngModelGroup=\"classroom\">\n <mat-label>\u6559\u5BA4</mat-label>\n <mat-select [(ngModel)]=\"course.classroom\" name=\"id\">\n @for (classroom of classrooms; track classroom) {\n <mat-option [value]=\"classroom.id\">\n <div class=\"flex gap-3\">\n <span>{{ classroom.name }}</span>\n <span> {{ classroom.address }}</span>\n </div>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n </div>\n <div>\n <div class=\"py-3\">\n <h2>\u56FE\u7247\u4FE1\u606F</h2>\n </div>\n <rolatech-media-list (upload)=\"onUpload($event)\" [isUploading]=\"isUploading\">\n @for (item of course.media; track item; let i = $index) {\n <rolatech-media-list-item [media]=\"item\" (mediaItemClick)=\"onImageClick(i)\"></rolatech-media-list-item>\n }\n </rolatech-media-list>\n </div>\n </form>\n </mat-step>\n <mat-step [editable]=\"true\">\n <form #detailForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of course.details; track item) {\n <rolatech-detail-item\n [detail]=\"item\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n ></rolatech-detail-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addDetail()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n </form>\n </mat-step>\n <mat-step [editable]=\"true\">\n <form #pricingForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u4EF7\u683C</ng-template>\n <div>\n @for (item of course.pricing; track item) {\n <rolatech-pricing-item [pricing]=\"item\"> </rolatech-pricing-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addPricing()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n </div>\n </form>\n </mat-step>\n <mat-step>\n <form #scheduleForm=\"ngForm\">\n <ng-template matStepLabel>\u8BFE\u8868</ng-template>\n <div class=\"flex flex-col\">\n @for (item of course.schedule; track item) {\n <rolatech-schedule-item [value]=\"item\"></rolatech-schedule-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addSchedule()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n </div>\n </form>\n </mat-step>\n </mat-stepper>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n @if (!firstStepper) {\n <button mat-button mat-button (click)=\"previous()\">\u4E0A\u4E00\u6B65</button>\n }\n @if (!lastStepper) {\n <button mat-button (click)=\"next()\">\u4E0B\u4E00\u6B65</button>\n }\n @if (lastStepper) {\n <button mat-button [mat-dialog-close]=\"course\" cdkFocusInitial>\u4FDD\u5B58</button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i7$1.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i7$1.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i7$1.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i7.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: MediaListComponent, selector: "rolatech-media-list", inputs: ["isUploading", "media", "showAdd"], outputs: ["mediaItemClick", "upload"] }, { kind: "component", type: MediaListItemComponent, selector: "rolatech-media-list-item", inputs: ["media", "uploadProgress"], outputs: ["mediaItemClick", "deleteMedia"] }, { kind: "component", type: DetailItemComponent, selector: "rolatech-detail-item", inputs: ["isUploading", "detail", "actions", "selectMedia"], outputs: ["upload", "delete", "save", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: PricingItemComponent, selector: "rolatech-pricing-item", inputs: ["actions", "pricing"], outputs: ["pricingChange", "delete", "save"] }, { kind: "component", type: ScheduleItemComponent, selector: "rolatech-schedule-item", inputs: ["value", "actions"], outputs: ["delete", "save"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1496
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseEditDialogComponent, isStandalone: true, selector: "rolatech-course-edit-dialog", viewQueries: [{ propertyName: "stepper", first: true, predicate: MatStepper, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex flex-col h-full overflow-hidden\">\n <div class=\"h-16 flex justify-between items-center px-5\">\n @if (data.title) {\n <div class=\"text-md font-medium\">{{ data.title }}</div>\n }\n <div class=\"cursor-pointer\" (click)=\"close()\">\n <mat-icon fontIcon=\"close\"></mat-icon>\n </div>\n </div>\n <mat-divider></mat-divider>\n <div class=\"flex-1 overflow-hidden mt-3 overflow-y-auto\">\n <mat-stepper #stepper (selectionChange)=\"onStepperChange($event)\">\n <mat-step [editable]=\"true\">\n <form #infoForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u57FA\u672C\u4FE1\u606F</ng-template>\n <div class=\"flex flex-col\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u540D\u79F0 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"course.name\" name=\"name\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u63CF\u8FF0 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"course.description\"\n name=\"description\"\n required\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" ngModelGroup=\"categories\">\n <mat-label>\u5206\u7C7B</mat-label>\n <mat-select\n multiple\n name=\"id\"\n [compareWith]=\"compareFn\"\n [(ngModel)]=\"course.categories\"\n #select=\"matSelect\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n @for (item of categories; track item) {\n <mat-option [value]=\"item\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7C7B\u578B</mat-label>\n <mat-select name=\"type\" [(ngModel)]=\"course.type\">\n @for (item of courseType; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (course.type.toString() !== 'ONLINE') {\n <mat-form-field appearance=\"fill\" ngModelGroup=\"classroom\">\n <mat-label>\u6559\u5BA4</mat-label>\n <mat-select [(ngModel)]=\"course.classroom\" name=\"id\">\n @for (classroom of classrooms; track classroom) {\n <mat-option [value]=\"classroom.id\">\n <div class=\"flex gap-3\">\n <span>{{ classroom.name }}</span>\n <span> {{ classroom.address }}</span>\n </div>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n </div>\n <div>\n <div class=\"py-3\">\n <h2>\u56FE\u7247\u4FE1\u606F</h2>\n </div>\n <rolatech-media-list (upload)=\"onUpload($event)\" [isUploading]=\"isUploading\">\n @for (item of course.media; track item; let i = $index) {\n <rolatech-media-list-item [media]=\"item\" (mediaItemClick)=\"onImageClick(i)\"></rolatech-media-list-item>\n }\n </rolatech-media-list>\n </div>\n </form>\n </mat-step>\n <mat-step [editable]=\"true\">\n <form #detailForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u8BE6\u60C5</ng-template>\n @for (item of course.details; track item) {\n <rolatech-detail-item\n [detail]=\"item\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n ></rolatech-detail-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addDetail()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n </form>\n </mat-step>\n <mat-step [editable]=\"true\">\n <form #pricingForm=\"ngForm\" class=\"py-3\">\n <ng-template matStepLabel>\u4EF7\u683C</ng-template>\n <div>\n @for (item of course.pricing; track item) {\n <rolatech-pricing-item [pricing]=\"item\"> </rolatech-pricing-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addPricing()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n </div>\n </form>\n </mat-step>\n <mat-step>\n <form #scheduleForm=\"ngForm\">\n <ng-template matStepLabel>\u8BFE\u8868</ng-template>\n <div class=\"flex flex-col\">\n @for (item of course.schedule; track item) {\n <rolatech-schedule-item [value]=\"item\"></rolatech-schedule-item>\n }\n <div class=\"mb-6\">\n <button mat-button (click)=\"addSchedule()\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n </div>\n </form>\n </mat-step>\n </mat-stepper>\n </div>\n <mat-divider></mat-divider>\n <div class=\"h-16 flex justify-end items-center px-5\">\n @if (!firstStepper) {\n <button mat-button mat-button (click)=\"previous()\">\u4E0A\u4E00\u6B65</button>\n }\n @if (!lastStepper) {\n <button mat-button (click)=\"next()\">\u4E0B\u4E00\u6B65</button>\n }\n @if (lastStepper) {\n <button mat-button [mat-dialog-close]=\"course\" cdkFocusInitial>\u4FDD\u5B58</button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i5$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatStepperModule }, { kind: "component", type: i7.MatStep, selector: "mat-step", inputs: ["color"], exportAs: ["matStep"] }, { kind: "directive", type: i7.MatStepLabel, selector: "[matStepLabel]" }, { kind: "component", type: i7.MatStepper, selector: "mat-stepper, mat-vertical-stepper, mat-horizontal-stepper, [matStepper]", inputs: ["disableRipple", "color", "labelPosition", "headerPosition", "animationDuration"], outputs: ["animationDone"], exportAs: ["matStepper", "matVerticalStepper", "matHorizontalStepper"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "component", type: MediaListComponent, selector: "rolatech-media-list", inputs: ["isUploading", "media", "showAdd"], outputs: ["mediaItemClick", "upload"] }, { kind: "component", type: MediaListItemComponent, selector: "rolatech-media-list-item", inputs: ["media", "uploadProgress"], outputs: ["mediaItemClick", "deleteMedia"] }, { kind: "component", type: DetailItemComponent, selector: "rolatech-detail-item", inputs: ["isUploading", "detail", "actions", "selectMedia"], outputs: ["upload", "delete", "save", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: PricingItemComponent, selector: "rolatech-pricing-item", inputs: ["actions", "pricing"], outputs: ["pricingChange", "delete", "save"] }, { kind: "component", type: ScheduleItemComponent, selector: "rolatech-schedule-item", inputs: ["value", "actions"], outputs: ["delete", "save"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] }); }
1496
1497
  }
1497
1498
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseEditDialogComponent, decorators: [{
1498
1499
  type: Component,
@@ -1928,7 +1929,7 @@ const courseRoutes = [
1928
1929
  children: [
1929
1930
  {
1930
1931
  path: '',
1931
- loadComponent: () => import('./rolatech-angular-course-course-index.component-Bm6Sg8zH.mjs').then((x) => x.CourseIndexComponent),
1932
+ loadComponent: () => import('./rolatech-angular-course-course-index.component-BiS-U0WO.mjs').then((x) => x.CourseIndexComponent),
1932
1933
  },
1933
1934
  {
1934
1935
  path: 'categories/:id',
@@ -1950,9 +1951,1090 @@ const courseRoutes = [
1950
1951
  },
1951
1952
  ];
1952
1953
 
1954
+ class CourseManageContentComponent {
1955
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1956
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: CourseManageContentComponent, isStandalone: true, selector: "rolatech-course-manage-content", ngImport: i0, template: "<ng-content select=\"rolatech-toolbar\"></ng-content>\n<div class=\"p-3\">\n <ng-content></ng-content>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
1957
+ }
1958
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageContentComponent, decorators: [{
1959
+ type: Component,
1960
+ args: [{ selector: 'rolatech-course-manage-content', standalone: true, imports: [CommonModule], template: "<ng-content select=\"rolatech-toolbar\"></ng-content>\n<div class=\"p-3\">\n <ng-content></ng-content>\n</div>\n" }]
1961
+ }] });
1962
+
1963
+ class CourseManageDetailsComponent {
1964
+ constructor() {
1965
+ this.route = inject(ActivatedRoute);
1966
+ this.courseService = inject(CourseService);
1967
+ this.dialog = inject(MatDialog);
1968
+ this.snackBar = inject(MatSnackBar);
1969
+ this.isLoading = false;
1970
+ this.isUploading = false;
1971
+ this.details = [];
1972
+ this.status = CourseStatus;
1973
+ this.courseType = CourseType;
1974
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
1975
+ }
1976
+ ngOnInit() {
1977
+ this.find();
1978
+ }
1979
+ find() {
1980
+ this.courseService.findDetails(this.id).subscribe({
1981
+ next: (res) => {
1982
+ if (res.data) {
1983
+ this.details = res.data;
1984
+ }
1985
+ },
1986
+ });
1987
+ }
1988
+ addDetail() {
1989
+ if (!this.details) {
1990
+ this.details = [];
1991
+ }
1992
+ this.courseService
1993
+ .addDetail(this.id, {
1994
+ title: '',
1995
+ description: '',
1996
+ content: '',
1997
+ media: [],
1998
+ })
1999
+ .subscribe({
2000
+ next: (res) => {
2001
+ const detail = res.data;
2002
+ this.details.push({
2003
+ id: detail.id,
2004
+ title: '',
2005
+ description: '',
2006
+ content: '',
2007
+ media: [],
2008
+ });
2009
+ },
2010
+ error: (e) => {
2011
+ this.snackBar.open(e.message);
2012
+ },
2013
+ });
2014
+ }
2015
+ onDetailMediaUpload(event) {
2016
+ const detailId = event.id;
2017
+ const index = findIndex(this.details, (item) => item.id === detailId);
2018
+ const file = event.data.target.files[0];
2019
+ if (file) {
2020
+ const reader = new FileReader();
2021
+ reader.readAsDataURL(file);
2022
+ reader.onload = () => {
2023
+ if (!this.details[index].media) {
2024
+ this.details[index].media = [];
2025
+ }
2026
+ this.details[index].media.push({
2027
+ url: reader.result,
2028
+ alt: 'upload image',
2029
+ });
2030
+ this.details[index].isUploading = true;
2031
+ const formData = new FormData();
2032
+ formData.append('file', file);
2033
+ this.courseService.uploadDetailMedia(this.id, detailId, formData).subscribe({
2034
+ next: (res) => {
2035
+ this.isUploading = false;
2036
+ this.details[index].isUploading = false;
2037
+ const tmp = this.details[index].media;
2038
+ delete res.data.productDetail;
2039
+ this.details[index].media[this.details[index].media.length - 1] = res.data;
2040
+ },
2041
+ error: (e) => {
2042
+ this.isUploading = false;
2043
+ this.snackBar.open('上传失败: ' + e.message);
2044
+ },
2045
+ });
2046
+ };
2047
+ reader.onerror = (error) => {
2048
+ this.isUploading = false;
2049
+ };
2050
+ }
2051
+ }
2052
+ onDetailMediaDelete(event) {
2053
+ const detailId = event.id;
2054
+ const mediaId = event.media.id;
2055
+ this.courseService.deleteDetailMedia(this.id, detailId, mediaId).subscribe({
2056
+ next: (res) => {
2057
+ const detail = this.details.find((item) => item.id === detailId);
2058
+ remove(detail.media, {
2059
+ id: mediaId,
2060
+ });
2061
+ },
2062
+ });
2063
+ }
2064
+ onDetailSave(detail) {
2065
+ delete detail.isUploading;
2066
+ this.courseService.updateDetail(this.id, detail.id, detail).subscribe({
2067
+ next: (res) => {
2068
+ this.snackBar.open('保存成功');
2069
+ },
2070
+ error: (e) => {
2071
+ this.snackBar.open(e.message);
2072
+ },
2073
+ });
2074
+ }
2075
+ onDetailDelete(detail) {
2076
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
2077
+ width: '400px',
2078
+ data: {
2079
+ title: '删除详情',
2080
+ message: '确定删除此详情吗?',
2081
+ },
2082
+ });
2083
+ dialogRef.afterClosed().subscribe((result) => {
2084
+ if (result) {
2085
+ this.courseService.deleteDetail(this.id, detail.id).subscribe({
2086
+ next: (res) => {
2087
+ this.snackBar.open(res.data);
2088
+ remove(this.details, {
2089
+ id: detail.id,
2090
+ });
2091
+ },
2092
+ error: (e) => {
2093
+ this.snackBar.open(e.message);
2094
+ },
2095
+ });
2096
+ }
2097
+ });
2098
+ }
2099
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2100
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageDetailsComponent, isStandalone: true, selector: "rolatech-course-manage-details", ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u8BE6\u60C5\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (detail of details; track detail) {\n <rolatech-detail-item\n [detail]=\"detail\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n [actions]=\"true\"\n ></rolatech-detail-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addDetail()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u6DFB\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n", styles: [""], dependencies: [{ kind: "component", type: DetailItemComponent, selector: "rolatech-detail-item", inputs: ["isUploading", "detail", "actions", "selectMedia"], outputs: ["upload", "delete", "save", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2101
+ }
2102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageDetailsComponent, decorators: [{
2103
+ type: Component,
2104
+ args: [{ selector: 'rolatech-course-manage-details', standalone: true, imports: [DetailItemComponent, MatButtonModule, MatIconModule, ToolbarComponent, CourseManageContentComponent], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u8BE6\u60C5\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (detail of details; track detail) {\n <rolatech-detail-item\n [detail]=\"detail\"\n (upload)=\"onDetailMediaUpload($event)\"\n (deleteMedia)=\"onDetailMediaDelete($event)\"\n (save)=\"onDetailSave($event)\"\n (delete)=\"onDetailDelete($event)\"\n [actions]=\"true\"\n ></rolatech-detail-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addDetail()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u6DFB\u52A0\u8BE6\u60C5</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n" }]
2105
+ }], ctorParameters: () => [] });
2106
+
2107
+ class CourseManageScheduleComponent {
2108
+ constructor() {
2109
+ this.route = inject(ActivatedRoute);
2110
+ this.courseService = inject(CourseService);
2111
+ this.dialog = inject(MatDialog);
2112
+ this.snackBar = inject(MatSnackBar);
2113
+ this.isLoading = false;
2114
+ this.schedule = [];
2115
+ this.status = CourseStatus;
2116
+ this.courseType = CourseType;
2117
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2118
+ }
2119
+ ngOnInit() {
2120
+ this.find();
2121
+ }
2122
+ find() {
2123
+ this.courseService.findSchedule(this.id).subscribe({
2124
+ next: (res) => {
2125
+ if (res.data) {
2126
+ this.schedule = res.data;
2127
+ }
2128
+ },
2129
+ });
2130
+ }
2131
+ addSchedule() {
2132
+ const dialogRef = this.dialog.open(CourseScheduleAddDialogComponent, {
2133
+ width: '500px',
2134
+ disableClose: true,
2135
+ data: {
2136
+ title: '添加课表',
2137
+ },
2138
+ });
2139
+ dialogRef.afterClosed().subscribe((schedule) => {
2140
+ if (schedule) {
2141
+ this.courseService.addSchedule(this.id, schedule).subscribe({
2142
+ next: (res) => {
2143
+ this.schedule.push(res.data);
2144
+ this.snackBar.open('添加成功');
2145
+ },
2146
+ error: (error) => {
2147
+ this.snackBar.open(error.message);
2148
+ },
2149
+ });
2150
+ }
2151
+ });
2152
+ }
2153
+ editSchedule() {
2154
+ const dialogRef = this.dialog.open(CourseScheduleDialogComponent, {
2155
+ width: '500px',
2156
+ height: '90%',
2157
+ data: {
2158
+ title: '编辑课表',
2159
+ courseId: this.id,
2160
+ schedule: this.schedule,
2161
+ },
2162
+ });
2163
+ dialogRef.afterClosed().subscribe((result) => {
2164
+ if (result) {
2165
+ this.courseService.addSchedule(this.id, { schedule: result }).subscribe({
2166
+ next: (res) => {
2167
+ this.snackBar.open('添加成功');
2168
+ },
2169
+ error: (error) => {
2170
+ this.snackBar.open(error.message);
2171
+ },
2172
+ });
2173
+ }
2174
+ });
2175
+ }
2176
+ onScheduleSave(schedule) {
2177
+ this.courseService.updateSchedule(this.id, schedule.id, schedule).subscribe({
2178
+ next: (res) => {
2179
+ this.snackBar.open('保存成功');
2180
+ },
2181
+ error: (e) => {
2182
+ this.snackBar.open(e.message);
2183
+ },
2184
+ });
2185
+ }
2186
+ onScheduleDelete(schedule) {
2187
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
2188
+ width: '400px',
2189
+ data: {
2190
+ title: '删除课表',
2191
+ message: '确定删除此课表吗?',
2192
+ },
2193
+ });
2194
+ dialogRef.afterClosed().subscribe((result) => {
2195
+ if (result) {
2196
+ this.courseService.deleteSchedule(this.id, schedule.id).subscribe({
2197
+ next: (res) => {
2198
+ remove(this.schedule, {
2199
+ id: schedule.id,
2200
+ });
2201
+ this.snackBar.open(res.data);
2202
+ },
2203
+ error: (e) => {
2204
+ this.snackBar.open(e.message);
2205
+ },
2206
+ });
2207
+ }
2208
+ });
2209
+ }
2210
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageScheduleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2211
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageScheduleComponent, isStandalone: true, selector: "rolatech-course-manage-schedule", ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u8BFE\u7A0B\u8868\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (item of schedule; track item) {\n <rolatech-schedule-item\n [value]=\"item\"\n [actions]=\"true\"\n (save)=\"onScheduleSave($event)\"\n (delete)=\"onScheduleDelete($event)\"\n >\n </rolatech-schedule-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addSchedule()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n", styles: [""], dependencies: [{ kind: "component", type: ScheduleItemComponent, selector: "rolatech-schedule-item", inputs: ["value", "actions"], outputs: ["delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2212
+ }
2213
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageScheduleComponent, decorators: [{
2214
+ type: Component,
2215
+ args: [{ selector: 'rolatech-course-manage-schedule', standalone: true, imports: [ScheduleItemComponent, MatButtonModule, MatIconModule, ToolbarComponent, CourseManageContentComponent], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u8BFE\u7A0B\u8868\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (item of schedule; track item) {\n <rolatech-schedule-item\n [value]=\"item\"\n [actions]=\"true\"\n (save)=\"onScheduleSave($event)\"\n (delete)=\"onScheduleDelete($event)\"\n >\n </rolatech-schedule-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addSchedule()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u8BFE\u8868</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n" }]
2216
+ }], ctorParameters: () => [] });
2217
+
2218
+ class CourseManagePricingComponent {
2219
+ constructor() {
2220
+ this.route = inject(ActivatedRoute);
2221
+ this.courseService = inject(CourseService);
2222
+ this.dialog = inject(MatDialog);
2223
+ this.snackBar = inject(MatSnackBar);
2224
+ this.isLoading = false;
2225
+ this.pricing = [];
2226
+ this.status = CourseStatus;
2227
+ this.courseType = CourseType;
2228
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2229
+ }
2230
+ ngOnInit() {
2231
+ this.find();
2232
+ }
2233
+ find() {
2234
+ this.courseService.findPricing(this.id).subscribe({
2235
+ next: (res) => {
2236
+ if (res.data) {
2237
+ this.pricing = res.data;
2238
+ }
2239
+ },
2240
+ });
2241
+ }
2242
+ editPricing() {
2243
+ const dialogRef = this.dialog.open(CoursePricingDialogComponent, {
2244
+ width: '500px',
2245
+ height: '90%',
2246
+ data: {
2247
+ title: '编辑价格',
2248
+ courseId: this.id,
2249
+ pricing: this.pricing,
2250
+ },
2251
+ });
2252
+ dialogRef.afterClosed().subscribe((result) => {
2253
+ if (result) {
2254
+ this.courseService.addPricing(this.id, { pricing: result }).subscribe({
2255
+ next: (res) => {
2256
+ this.snackBar.open('添加成功');
2257
+ },
2258
+ error: (error) => {
2259
+ this.snackBar.open(error.message);
2260
+ },
2261
+ });
2262
+ }
2263
+ });
2264
+ }
2265
+ addPricing() {
2266
+ const dialogRef = this.dialog.open(CoursePricingAddDialogComponent, {
2267
+ disableClose: true,
2268
+ width: '500px',
2269
+ data: {
2270
+ title: '添加价格',
2271
+ },
2272
+ });
2273
+ dialogRef.afterClosed().subscribe((pricing) => {
2274
+ if (pricing) {
2275
+ this.courseService.addPricing(this.id, { ...pricing, total: pricing.total * 100 }).subscribe({
2276
+ next: (res) => {
2277
+ this.pricing.push(res.data);
2278
+ this.snackBar.open('添加成功');
2279
+ },
2280
+ error: (error) => {
2281
+ this.snackBar.open(error.message);
2282
+ },
2283
+ });
2284
+ }
2285
+ });
2286
+ }
2287
+ onPricingSave(pricing) {
2288
+ this.courseService.updatePricing(this.id, pricing.id, pricing).subscribe({
2289
+ next: (res) => {
2290
+ this.snackBar.open('保存成功');
2291
+ },
2292
+ error: (e) => {
2293
+ this.snackBar.open(e.message);
2294
+ },
2295
+ });
2296
+ }
2297
+ onPricingDelete(pricing) {
2298
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
2299
+ width: '400px',
2300
+ data: {
2301
+ title: '删除价格',
2302
+ message: '确定删除此价格吗?',
2303
+ },
2304
+ });
2305
+ dialogRef.afterClosed().subscribe((result) => {
2306
+ if (result) {
2307
+ this.courseService.deletePricing(this.id, pricing.id).subscribe({
2308
+ next: (res) => {
2309
+ remove(this.pricing, {
2310
+ id: pricing.id,
2311
+ });
2312
+ this.snackBar.open(res.data);
2313
+ },
2314
+ error: (e) => {
2315
+ this.snackBar.open(e.message);
2316
+ },
2317
+ });
2318
+ }
2319
+ });
2320
+ }
2321
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManagePricingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2322
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManagePricingComponent, isStandalone: true, selector: "rolatech-course-manage-pricing", ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u4EF7\u683C\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (item of pricing; track item) {\n <rolatech-pricing-item\n [pricing]=\"item\"\n [actions]=\"true\"\n (save)=\"onPricingSave($event)\"\n (delete)=\"onPricingDelete($event)\"\n >\n </rolatech-pricing-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addPricing()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u6DFB\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n", styles: [""], dependencies: [{ kind: "component", type: PricingItemComponent, selector: "rolatech-pricing-item", inputs: ["actions", "pricing"], outputs: ["pricingChange", "delete", "save"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2323
+ }
2324
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManagePricingComponent, decorators: [{
2325
+ type: Component,
2326
+ args: [{ selector: 'rolatech-course-manage-pricing', standalone: true, imports: [PricingItemComponent, MatButtonModule, MatIconModule, ToolbarComponent, CourseManageContentComponent], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u4EF7\u683C\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (item of pricing; track item) {\n <rolatech-pricing-item\n [pricing]=\"item\"\n [actions]=\"true\"\n (save)=\"onPricingSave($event)\"\n (delete)=\"onPricingDelete($event)\"\n >\n </rolatech-pricing-item>\n }\n </div>\n <button mat-stroked-button (click)=\"addPricing()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u6DFB\u52A0\u4EF7\u683C</span>\n </button>\n </div>\n</rolatech-course-manage-content>\n" }]
2327
+ }], ctorParameters: () => [] });
2328
+
2329
+ class BookingService extends BaseService {
2330
+ init() {
2331
+ this.endpoint = 'partners/bookings';
2332
+ super.init();
2333
+ }
2334
+ items(options) {
2335
+ return this.http.get(`${this.actionUrl}/items`, {
2336
+ params: options,
2337
+ withCredentials: true,
2338
+ });
2339
+ }
2340
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: BookingService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
2341
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: BookingService, providedIn: 'root' }); }
2342
+ }
2343
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: BookingService, decorators: [{
2344
+ type: Injectable,
2345
+ args: [{
2346
+ providedIn: 'root',
2347
+ }]
2348
+ }] });
2349
+
2350
+ class InstructorService extends BaseService {
2351
+ init() {
2352
+ this.endpoint = 'instructors';
2353
+ super.init();
2354
+ }
2355
+ findMyClassrooms(options) {
2356
+ return this.http.get(`${this.actionUrl}/classrooms/me`, {
2357
+ params: options,
2358
+ withCredentials: true,
2359
+ });
2360
+ }
2361
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: InstructorService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
2362
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: InstructorService, providedIn: 'root' }); }
2363
+ }
2364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: InstructorService, decorators: [{
2365
+ type: Injectable,
2366
+ args: [{
2367
+ providedIn: 'root',
2368
+ }]
2369
+ }] });
2370
+
2371
+ class CourseManageInfoComponent extends BaseComponent {
2372
+ constructor() {
2373
+ super(...arguments);
2374
+ this.courseService = inject(CourseService);
2375
+ this.instructorService = inject(InstructorService);
2376
+ this.categoryService = inject(CategoryService);
2377
+ this.bookingService = inject(BookingService);
2378
+ this.isLoading = false;
2379
+ this.status = CourseStatus;
2380
+ this.courseType = [
2381
+ {
2382
+ key: 'ONLINE',
2383
+ value: '线上',
2384
+ },
2385
+ {
2386
+ key: 'OFFLINE',
2387
+ value: '线下',
2388
+ },
2389
+ {
2390
+ key: 'MIXED',
2391
+ value: '混合',
2392
+ },
2393
+ ];
2394
+ }
2395
+ ngOnInit() {
2396
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2397
+ this.find();
2398
+ this.categoryService.find({}).subscribe({
2399
+ next: (res) => {
2400
+ this.categories = res.data;
2401
+ },
2402
+ });
2403
+ this.findClassrooms();
2404
+ this.findBookedClassrooms();
2405
+ }
2406
+ findBookedClassrooms() {
2407
+ this.bookingService.items({ status: 'paid' }).subscribe({
2408
+ next: (res) => {
2409
+ this.bookedClassrooms = res.data;
2410
+ },
2411
+ });
2412
+ }
2413
+ findClassrooms() {
2414
+ this.instructorService.findMyClassrooms({}).subscribe({
2415
+ next: (res) => {
2416
+ this.classrooms = res.data;
2417
+ },
2418
+ });
2419
+ }
2420
+ find() {
2421
+ this.courseService.get(this.id).subscribe({
2422
+ next: (res) => {
2423
+ this.course = res.data;
2424
+ },
2425
+ });
2426
+ }
2427
+ compareFn(o1, o2) {
2428
+ return o1.id === o2?.id;
2429
+ }
2430
+ compareClassroom(o1, o2) {
2431
+ if (o1.room) {
2432
+ return (o1.latitude === o2?.latitude &&
2433
+ o1.longitude === o2?.longitude &&
2434
+ o1.room === o2.room &&
2435
+ o1.startAt === o2.startAt &&
2436
+ o1.endAt === o2.endAt);
2437
+ }
2438
+ else {
2439
+ return o1.latitude === o2?.latitude && o1.longitude === o2?.longitude;
2440
+ }
2441
+ }
2442
+ onSelectionChange(event) {
2443
+ this.selectedCategoyIds = event.value;
2444
+ }
2445
+ onClassroomSelected(event) {
2446
+ this.selectedClassroom = event.value;
2447
+ }
2448
+ update() {
2449
+ const { name, description, categories, type, classroom } = this.course;
2450
+ const finalClassroom = clone(classroom);
2451
+ finalClassroom.address = classroom.room ? classroom.address + ' ' + classroom.room + '室' : classroom.address;
2452
+ const data = {
2453
+ name,
2454
+ description,
2455
+ categories,
2456
+ type,
2457
+ classroom: finalClassroom,
2458
+ };
2459
+ this.courseService.update(this.id, data).subscribe({
2460
+ next: (res) => {
2461
+ this.snackBarService.open('保存成功');
2462
+ // this.router.navigate([`../${res.data.id}`], { relativeTo: this.route });
2463
+ },
2464
+ error: (e) => {
2465
+ this.snackBarService.open(e.message);
2466
+ },
2467
+ });
2468
+ }
2469
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageInfoComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2470
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageInfoComponent, isStandalone: true, selector: "rolatech-course-manage-info", usesInheritance: true, ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u57FA\u672C\u4FE1\u606F\" class=\"hidden sm:block\" divider></rolatech-toolbar>\n @if (course) {\n <div class=\"flex flex-col\">\n <form #courseForm=\"ngForm\" (ngSubmit)=\"update()\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u540D\u79F0 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"course.name\" name=\"name\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u63CF\u8FF0 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"course.description\"\n name=\"description\"\n required\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" ngModelGroup=\"categories\" required>\n <mat-label>\u5206\u7C7B</mat-label>\n <mat-select\n multiple\n name=\"id\"\n [compareWith]=\"compareFn\"\n [(ngModel)]=\"course.categories\"\n #select=\"matSelect\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n @for (item of categories; track item) {\n <mat-option [value]=\"item\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7C7B\u578B</mat-label>\n <mat-select name=\"type\" [(ngModel)]=\"course.type\" required>\n @for (item of courseType; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (course.type && course.type.toString() !== 'ONLINE') {\n <mat-form-field appearance=\"fill\" ngModelGroup=\"classroom\">\n <mat-label>\u6559\u5BA4</mat-label>\n <mat-select\n name=\"id\"\n [(ngModel)]=\"course.classroom\"\n [compareWith]=\"compareClassroom\"\n (selectionChange)=\"onClassroomSelected($event)\"\n required\n >\n <mat-optgroup label=\"\u81EA\u6709\u6559\u5BA4\">\n @for (classroom of classrooms; track classroom) {\n <mat-option [value]=\"classroom\">\n <div class=\"flex gap-3\">\n <span>{{ classroom.name }}</span>\n <span> {{ classroom.address }}</span>\n </div>\n </mat-option>\n }\n </mat-optgroup>\n <mat-optgroup label=\"\u5DF2\u8D2D\u6559\u5BA4\">\n @for (item of bookedClassrooms; track item) {\n <mat-option [value]=\"item\">\n <div class=\"flex flex-col py-3\">\n <span class=\"font-bold\"> {{ item.address }} {{ item.room }}\u5BA4</span>\n <span class=\"text-md font-thin\"> {{ item.startAt }} - {{ item.endAt }}</span>\n </div>\n </mat-option>\n }\n </mat-optgroup>\n </mat-select>\n </mat-form-field>\n }\n </form>\n </div>\n <div>\n <button mat-flat-button type=\"primary\" (click)=\"update()\">\u4FDD\u5B58</button>\n </div>\n }\n</rolatech-course-manage-content>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgModelGroup, selector: "[ngModelGroup]", inputs: ["ngModelGroup"], exportAs: ["ngModelGroup"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i3$1.CdkTextareaAutosize, selector: "textarea[cdkTextareaAutosize]", inputs: ["cdkAutosizeMinRows", "cdkAutosizeMaxRows", "cdkTextareaAutosize", "placeholder"], exportAs: ["cdkTextareaAutosize"] }, { kind: "ngmodule", type: TextFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6$2.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2471
+ }
2472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageInfoComponent, decorators: [{
2473
+ type: Component,
2474
+ args: [{ selector: 'rolatech-course-manage-info', standalone: true, imports: [
2475
+ FormsModule,
2476
+ MatFormFieldModule,
2477
+ MatInputModule,
2478
+ TextFieldModule,
2479
+ MatSelectModule,
2480
+ MatOptionModule,
2481
+ MatButtonModule,
2482
+ ToolbarComponent,
2483
+ CourseManageContentComponent,
2484
+ ], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u57FA\u672C\u4FE1\u606F\" class=\"hidden sm:block\" divider></rolatech-toolbar>\n @if (course) {\n <div class=\"flex flex-col\">\n <form #courseForm=\"ngForm\" (ngSubmit)=\"update()\">\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u540D\u79F0 </mat-label>\n <input matInput type=\"text\" [(ngModel)]=\"course.name\" name=\"name\" required />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label> \u8BFE\u7A0B\u63CF\u8FF0 </mat-label>\n <textarea\n matInput\n type=\"text\"\n [(ngModel)]=\"course.description\"\n name=\"description\"\n required\n cdkTextareaAutosize\n cdkAutosizeMinRows=\"3\"\n ></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" ngModelGroup=\"categories\" required>\n <mat-label>\u5206\u7C7B</mat-label>\n <mat-select\n multiple\n name=\"id\"\n [compareWith]=\"compareFn\"\n [(ngModel)]=\"course.categories\"\n #select=\"matSelect\"\n (selectionChange)=\"onSelectionChange($event)\"\n >\n @for (item of categories; track item) {\n <mat-option [value]=\"item\">\n {{ item.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label>\u7C7B\u578B</mat-label>\n <mat-select name=\"type\" [(ngModel)]=\"course.type\" required>\n @for (item of courseType; track item) {\n <mat-option [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (course.type && course.type.toString() !== 'ONLINE') {\n <mat-form-field appearance=\"fill\" ngModelGroup=\"classroom\">\n <mat-label>\u6559\u5BA4</mat-label>\n <mat-select\n name=\"id\"\n [(ngModel)]=\"course.classroom\"\n [compareWith]=\"compareClassroom\"\n (selectionChange)=\"onClassroomSelected($event)\"\n required\n >\n <mat-optgroup label=\"\u81EA\u6709\u6559\u5BA4\">\n @for (classroom of classrooms; track classroom) {\n <mat-option [value]=\"classroom\">\n <div class=\"flex gap-3\">\n <span>{{ classroom.name }}</span>\n <span> {{ classroom.address }}</span>\n </div>\n </mat-option>\n }\n </mat-optgroup>\n <mat-optgroup label=\"\u5DF2\u8D2D\u6559\u5BA4\">\n @for (item of bookedClassrooms; track item) {\n <mat-option [value]=\"item\">\n <div class=\"flex flex-col py-3\">\n <span class=\"font-bold\"> {{ item.address }} {{ item.room }}\u5BA4</span>\n <span class=\"text-md font-thin\"> {{ item.startAt }} - {{ item.endAt }}</span>\n </div>\n </mat-option>\n }\n </mat-optgroup>\n </mat-select>\n </mat-form-field>\n }\n </form>\n </div>\n <div>\n <button mat-flat-button type=\"primary\" (click)=\"update()\">\u4FDD\u5B58</button>\n </div>\n }\n</rolatech-course-manage-content>\n", styles: ["mat-form-field{width:100%}\n"] }]
2485
+ }] });
2486
+
2487
+ const SIZE = 10 * 1024 * 1024; // file slice size 10MB
2488
+ class CourseManageMediaComponent {
2489
+ constructor() {
2490
+ this.route = inject(ActivatedRoute);
2491
+ this.courseService = inject(CourseService);
2492
+ this.dialog = inject(MatDialog);
2493
+ this.snackBar = inject(MatSnackBar);
2494
+ this.isUploading = false;
2495
+ this.isLoading = false;
2496
+ this.media = [];
2497
+ this.status = CourseStatus;
2498
+ this.courseType = CourseType;
2499
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2500
+ }
2501
+ ngOnInit() {
2502
+ this.find();
2503
+ }
2504
+ find() {
2505
+ this.courseService.get(this.id).subscribe({
2506
+ next: (res) => {
2507
+ this.media = res.data.media || [];
2508
+ },
2509
+ });
2510
+ }
2511
+ onImageClick(i) {
2512
+ const dialogRef = this.dialog.open(ImagePreviewDialogComponent, {
2513
+ maxWidth: '80vw',
2514
+ maxHeight: '80vh',
2515
+ height: '80%',
2516
+ width: '80%',
2517
+ panelClass: 'full-screen-modal',
2518
+ data: {
2519
+ media: this.media,
2520
+ selected: i,
2521
+ },
2522
+ });
2523
+ dialogRef.afterClosed().subscribe((result) => { });
2524
+ }
2525
+ createFileChunk(file, size = SIZE) {
2526
+ const fileChunkList = [];
2527
+ let cur = 0;
2528
+ while (cur < file.size) {
2529
+ fileChunkList.push({ file: file.slice(cur, cur + size) });
2530
+ cur += size;
2531
+ }
2532
+ return fileChunkList;
2533
+ }
2534
+ onUploadMedia2(event) {
2535
+ const file = event.target.files[0];
2536
+ const reader = new FileReader();
2537
+ reader.onload = (e) => { };
2538
+ const fileChunkList = this.createFileChunk(file);
2539
+ fileChunkList.forEach((item) => { });
2540
+ }
2541
+ onUploadMedia(event) {
2542
+ const file = event.target.files[0];
2543
+ // 5MB * 1024 * 1024 = 5242880
2544
+ // if (file?.size > 5242880) {
2545
+ // this.snackBar.open('尺寸过大, 请修改后上传');
2546
+ // this.isUploading = false;
2547
+ // return;
2548
+ // }
2549
+ if (file) {
2550
+ const reader = new FileReader();
2551
+ const formData = new FormData();
2552
+ formData.append('file', file);
2553
+ reader.readAsDataURL(file);
2554
+ reader.onload = () => {
2555
+ const img = new Image();
2556
+ img.onload = () => {
2557
+ this.media.push({
2558
+ url: img.src,
2559
+ alt: 'upload image',
2560
+ width: img.width,
2561
+ height: img.height,
2562
+ });
2563
+ this.isUploading = true;
2564
+ };
2565
+ img.src = reader.result; // This is the data URL
2566
+ };
2567
+ this.courseService.uploadMedia(this.id, formData).subscribe({
2568
+ next: (res) => {
2569
+ this.isUploading = false;
2570
+ const index = findLastIndex(this.media);
2571
+ // Replace item at index using native splice
2572
+ this.media.splice(index, 1, res.data);
2573
+ },
2574
+ error: (e) => {
2575
+ this.isUploading = false;
2576
+ this.snackBar.open('上传失败: ' + e.message);
2577
+ },
2578
+ });
2579
+ reader.onerror = (error) => {
2580
+ this.isUploading = false;
2581
+ };
2582
+ }
2583
+ }
2584
+ onMediaDelete(item) {
2585
+ const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
2586
+ width: '400px',
2587
+ data: {
2588
+ title: '删除图片',
2589
+ message: '确定删除这张课程图片吗?',
2590
+ },
2591
+ });
2592
+ dialogRef.afterClosed().subscribe((result) => {
2593
+ if (result) {
2594
+ this.courseService.deleteMedia(this.id, item.id).subscribe({
2595
+ next: (res) => {
2596
+ this.media = this.media.filter((m) => m.id !== item.id);
2597
+ this.snackBar.open('删除成功');
2598
+ },
2599
+ error: (e) => {
2600
+ this.snackBar.open(e.message);
2601
+ },
2602
+ });
2603
+ }
2604
+ });
2605
+ }
2606
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageMediaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2607
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageMediaComponent, isStandalone: true, selector: "rolatech-course-manage-media", ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u56FE\u7247\u4FE1\u606F\" class=\"hidden sm:block\" divider></rolatech-toolbar>\n <div>\n <p class=\"text-gray-600\">*\u56FE\u7247\u6587\u4EF6\u5927\u5C0F\u9650\u5236\u57285MB\u4EE5\u4E0B*</p>\n <rolatech-media-list (upload)=\"onUploadMedia($event)\" [isUploading]=\"isUploading\">\n @for (item of media; track item; let i = $index) {\n <rolatech-media-list-item\n [media]=\"item\"\n (mediaItemClick)=\"onImageClick(i)\"\n (deleteMedia)=\"onMediaDelete(item)\"\n ></rolatech-media-list-item>\n }\n </rolatech-media-list>\n </div>\n</rolatech-course-manage-content>\n", styles: [""], dependencies: [{ kind: "component", type: MediaListComponent, selector: "rolatech-media-list", inputs: ["isUploading", "media", "showAdd"], outputs: ["mediaItemClick", "upload"] }, { kind: "component", type: MediaListItemComponent, selector: "rolatech-media-list-item", inputs: ["media", "uploadProgress"], outputs: ["mediaItemClick", "deleteMedia"] }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2608
+ }
2609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageMediaComponent, decorators: [{
2610
+ type: Component,
2611
+ args: [{ selector: 'rolatech-course-manage-media', standalone: true, imports: [MediaListComponent, MediaListItemComponent, ToolbarComponent, CourseManageContentComponent], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u56FE\u7247\u4FE1\u606F\" class=\"hidden sm:block\" divider></rolatech-toolbar>\n <div>\n <p class=\"text-gray-600\">*\u56FE\u7247\u6587\u4EF6\u5927\u5C0F\u9650\u5236\u57285MB\u4EE5\u4E0B*</p>\n <rolatech-media-list (upload)=\"onUploadMedia($event)\" [isUploading]=\"isUploading\">\n @for (item of media; track item; let i = $index) {\n <rolatech-media-list-item\n [media]=\"item\"\n (mediaItemClick)=\"onImageClick(i)\"\n (deleteMedia)=\"onMediaDelete(item)\"\n ></rolatech-media-list-item>\n }\n </rolatech-media-list>\n </div>\n</rolatech-course-manage-content>\n" }]
2612
+ }], ctorParameters: () => [] });
2613
+
2614
+ class CourseManageSectionComponent extends BaseComponent {
2615
+ constructor() {
2616
+ super(...arguments);
2617
+ this.courseService = inject(CourseService);
2618
+ this.sections = [];
2619
+ this.hasUnsaved = false;
2620
+ this.editId = '';
2621
+ this.lectureEditId = '';
2622
+ this.chunkSize = 5 * 1024 * 1024; // 切片大小
2623
+ this.fileIndex = 0; // 当前正在被遍历的文件下标
2624
+ }
2625
+ ngOnInit() {
2626
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2627
+ this.find();
2628
+ }
2629
+ find() {
2630
+ this.courseService.getCourseSection(this.id).subscribe({
2631
+ next: (res) => {
2632
+ if (res.data) {
2633
+ this.sections = res.data;
2634
+ }
2635
+ },
2636
+ });
2637
+ }
2638
+ addSection() {
2639
+ const section = {
2640
+ title: '',
2641
+ description: '',
2642
+ };
2643
+ this.courseService.addCourseSection(this.id, section).subscribe({
2644
+ next: (res) => {
2645
+ this.sections.push(res.data);
2646
+ this.editId = res.data.id;
2647
+ },
2648
+ });
2649
+ this.hasUnsaved = false;
2650
+ }
2651
+ onCancel(event) {
2652
+ this.sections.pop();
2653
+ this.hasUnsaved = false;
2654
+ }
2655
+ onSectionSave(event) {
2656
+ const { id } = event;
2657
+ this.courseService.updateCourseSection(id, event).subscribe({
2658
+ next: (res) => {
2659
+ this.hasUnsaved = false;
2660
+ this.snackBarService.open('保存成功');
2661
+ },
2662
+ });
2663
+ this.hasUnsaved = false;
2664
+ }
2665
+ onSectionEdit(event) {
2666
+ this.editId = event.id;
2667
+ // this.editIndex = this.sections.find((item: any) => item.id === event.id);
2668
+ }
2669
+ onSectionDelete(event) {
2670
+ const { id } = event;
2671
+ const options = {
2672
+ title: '确认删除吗',
2673
+ message: '删除这个章节吗?',
2674
+ cancelText: '取消',
2675
+ confirmText: '确认',
2676
+ };
2677
+ this.dialogService.open(options);
2678
+ this.dialogService.confirmed().subscribe({
2679
+ next: (res) => {
2680
+ if (res) {
2681
+ const data = {
2682
+ name: res,
2683
+ };
2684
+ this.courseService.deleteCourseSection(id).subscribe({
2685
+ next: (res) => {
2686
+ this.sections.pop();
2687
+ this.hasUnsaved = false;
2688
+ this.snackBarService.open(res.data);
2689
+ },
2690
+ error: (error) => {
2691
+ this.snackBarService.open(error.message);
2692
+ },
2693
+ });
2694
+ }
2695
+ },
2696
+ });
2697
+ }
2698
+ addLecture(section) {
2699
+ const lecture = {
2700
+ title: '',
2701
+ type: 'VIDEO',
2702
+ };
2703
+ this.courseService.addLecture(section.id, lecture).subscribe({
2704
+ next: (res) => {
2705
+ this.lectureEditId = res.data.id;
2706
+ if (section.lectures) {
2707
+ section.lectures.push(res.data);
2708
+ }
2709
+ else {
2710
+ const lectures = [];
2711
+ lectures.push(res.data);
2712
+ section.lectures = lectures;
2713
+ }
2714
+ },
2715
+ });
2716
+ }
2717
+ onAddLecture(event) { }
2718
+ onLectureSave(lecture) {
2719
+ this.courseService.updateLecture(lecture.id, lecture).subscribe({
2720
+ next: (res) => {
2721
+ this.snackBarService.open('保存成功');
2722
+ },
2723
+ });
2724
+ }
2725
+ onLectureEdit(lecture) { }
2726
+ onMediaEdit(lecture, video) {
2727
+ const { id } = lecture;
2728
+ const options = {
2729
+ title: lecture.title,
2730
+ cancelText: '取消',
2731
+ confirmText: '保存',
2732
+ data: lecture,
2733
+ width: '80vw',
2734
+ height: '100%',
2735
+ component: CourseSectionLectureVideoDialogComponent,
2736
+ };
2737
+ this.dialogService.open(options);
2738
+ this.dialogService.confirmed().subscribe({
2739
+ next: (res) => {
2740
+ if (res) {
2741
+ // this.courseService.deleteLecture(id).subscribe({
2742
+ // next: (res) => {},
2743
+ // error: (error) => {
2744
+ // this.snackBarService.open(error.message);
2745
+ // },
2746
+ // });
2747
+ }
2748
+ },
2749
+ });
2750
+ }
2751
+ onLectureDelete(section, lecture) {
2752
+ const { id } = lecture;
2753
+ const options = {
2754
+ title: '确认删除吗',
2755
+ message: '删除这一小节吗?',
2756
+ cancelText: '取消',
2757
+ confirmText: '确认',
2758
+ };
2759
+ this.dialogService.open(options);
2760
+ this.dialogService.confirmed().subscribe({
2761
+ next: (res) => {
2762
+ if (res) {
2763
+ this.courseService.deleteLecture(id).subscribe({
2764
+ next: (res) => {
2765
+ const index = section.lectures.findIndex((item) => item.id === id);
2766
+ section.lectures.splice(index, 1);
2767
+ this.hasUnsaved = false;
2768
+ this.snackBarService.open(res.data);
2769
+ },
2770
+ error: (error) => {
2771
+ this.snackBarService.open(error.message);
2772
+ },
2773
+ });
2774
+ }
2775
+ },
2776
+ });
2777
+ }
2778
+ onMediaUploadInit(lecture, event) {
2779
+ const file = event.data.target.files[0];
2780
+ if (!file) {
2781
+ return;
2782
+ }
2783
+ const item = {
2784
+ url: URL.createObjectURL(file),
2785
+ };
2786
+ lecture.item = item;
2787
+ lecture.isUploading = true;
2788
+ lecture.item.progress = 0;
2789
+ const reader = new FileReader();
2790
+ if (reader.readyState === FileReader.EMPTY) {
2791
+ reader.onload = async (e) => {
2792
+ const fileBuffer = e.target.result;
2793
+ crypto.subtle.digest('SHA-256', fileBuffer).then((res) => {
2794
+ const hashArray = Array.from(new Uint8Array(res));
2795
+ const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, '0')).join('');
2796
+ const data = { hash: hashHex, filename: file.name, fileType: file.type };
2797
+ this.courseService.uploadVideoInit(lecture.id, data).subscribe({
2798
+ next: (res) => {
2799
+ this.uploadPart(lecture, res.data.uploadId, file);
2800
+ },
2801
+ error: (e) => { },
2802
+ });
2803
+ });
2804
+ };
2805
+ reader.onerror = (error) => { };
2806
+ reader.readAsArrayBuffer(file);
2807
+ }
2808
+ }
2809
+ uploadFile(lecture, file, index, uploadId) {
2810
+ const reader = new FileReader();
2811
+ return new Observable((observer) => {
2812
+ reader.readAsArrayBuffer(file);
2813
+ reader.onload = (e) => {
2814
+ const fileBuffer = e.target.result;
2815
+ crypto.subtle.digest('SHA-256', fileBuffer).then((res) => {
2816
+ const hashArray = Array.from(new Uint8Array(res));
2817
+ const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, '0')).join('');
2818
+ const formData = new FormData();
2819
+ formData.append('file', file);
2820
+ formData.append('uploadId', uploadId);
2821
+ formData.append('number', index + 1);
2822
+ formData.append('hash', hashHex);
2823
+ this.courseService.uploadVideoPartsToLecture(lecture.id, formData).subscribe({
2824
+ next: (res) => {
2825
+ observer.next(res);
2826
+ observer.complete();
2827
+ },
2828
+ error: (e) => {
2829
+ this.snackBarService.open('上传失败: ' + e.message);
2830
+ },
2831
+ });
2832
+ });
2833
+ };
2834
+ reader.onerror = (error) => {
2835
+ this.snackBarService.open('上传失败: ' + error);
2836
+ };
2837
+ });
2838
+ }
2839
+ uploadPart(lecture, uploadId, file) {
2840
+ let uploadedCount = 0;
2841
+ const fileChunkList = this.createFileChunk(file);
2842
+ const numberOfChunks = fileChunkList.length;
2843
+ from(fileChunkList)
2844
+ .pipe(concatMap((val, index) => this.uploadFile(lecture, val.file, index, uploadId)), take(numberOfChunks))
2845
+ .subscribe((res) => {
2846
+ uploadedCount++;
2847
+ const p = ((uploadedCount / numberOfChunks) * 100).toFixed(0);
2848
+ lecture.item.progress = parseFloat(p);
2849
+ if (uploadedCount === numberOfChunks) {
2850
+ console.log('done');
2851
+ this.completePartUpload(lecture, { uploadId });
2852
+ }
2853
+ });
2854
+ }
2855
+ completePartUpload(lecture, data) {
2856
+ data.duration = lecture.item.duration;
2857
+ this.courseService.completePartUpload(lecture.id, data).subscribe({
2858
+ next: (res) => {
2859
+ lecture.isUploading = false;
2860
+ lecture.item.id = res.data.id;
2861
+ },
2862
+ error: (e) => {
2863
+ this.snackBarService.open('上传失败: ' + e.message);
2864
+ },
2865
+ });
2866
+ }
2867
+ onMediaUpload(lecture, event) {
2868
+ const lectureId = event.id;
2869
+ const file = event.data.target.files[0];
2870
+ if (!file) {
2871
+ return;
2872
+ }
2873
+ const reader = new FileReader();
2874
+ reader.readAsDataURL(file);
2875
+ reader.onload = () => {
2876
+ const formData = new FormData();
2877
+ formData.append('file', file);
2878
+ this.courseService.uploadVideoToLecture(lectureId, formData).subscribe({
2879
+ next: (res) => {
2880
+ lecture.isUploading = false;
2881
+ lecture.item = res.data;
2882
+ },
2883
+ error: (e) => {
2884
+ lecture.isUploading = false;
2885
+ this.snackBarService.open('上传失败: ' + e.message);
2886
+ },
2887
+ });
2888
+ };
2889
+ reader.onerror = (error) => { };
2890
+ }
2891
+ onMediaDelete(lecture, event) {
2892
+ // lecture.item = null;
2893
+ const { id } = event;
2894
+ const options = {
2895
+ title: '确认删除吗',
2896
+ message: '删除这个视频吗?',
2897
+ cancelText: '取消',
2898
+ confirmText: '确认',
2899
+ };
2900
+ this.dialogService.open(options);
2901
+ this.dialogService.confirmed().subscribe({
2902
+ next: (res) => {
2903
+ if (res) {
2904
+ this.courseService.deleteLectureVideo(id).subscribe({
2905
+ next: (res) => {
2906
+ lecture.item = null;
2907
+ this.snackBarService.open(res.data);
2908
+ },
2909
+ error: (error) => {
2910
+ this.snackBarService.open(error.message);
2911
+ },
2912
+ });
2913
+ }
2914
+ },
2915
+ });
2916
+ }
2917
+ createFileChunk(file, size = this.chunkSize) {
2918
+ const fileChunkList = [];
2919
+ let count = 0;
2920
+ while (count < file.size) {
2921
+ fileChunkList.push({
2922
+ file: file.slice(count, count + size),
2923
+ });
2924
+ count += size;
2925
+ }
2926
+ return fileChunkList;
2927
+ }
2928
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageSectionComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2929
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageSectionComponent, isStandalone: true, selector: "rolatech-course-manage-section", usesInheritance: true, ngImport: i0, template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u7AE0\u8282\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (section of sections; track $index) {\n <div class=\"bg-gray-100 p-2 mb-2 rounded-lg\">\n <rolatech-course-section-item\n [section]=\"section\"\n (edit)=\"onSectionEdit($event)\"\n (save)=\"onSectionSave($event)\"\n (delete)=\"onSectionDelete($event)\"\n [editId]=\"editId\"\n >\n <div class=\"bg-white sm:ml-8 mt-3 rounded-md divide-y divide-dashed\">\n @if (section?.lectures) {\n @for (lecture of section.lectures; track $index) {\n <div>\n <rolatech-course-section-lecture-item\n [lecture]=\"lecture\"\n (save)=\"onLectureSave($event)\"\n (delete)=\"onLectureDelete(section, $event)\"\n (edit)=\"onLectureEdit($event)\"\n (upload)=\"onMediaUploadInit(lecture, $event)\"\n (mediaEdit)=\"onMediaEdit(lecture, $event)\"\n (deleteMedia)=\"onMediaDelete(lecture, $event)\"\n [editId]=\"lectureEditId\"\n ></rolatech-course-section-lecture-item>\n </div>\n }\n }\n <div class=\"p-2\">\n <button mat-flat-button (click)=\"addLecture(section)\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u5C0F\u8282</span>\n </button>\n </div>\n </div>\n </rolatech-course-section-item>\n </div>\n }\n </div>\n @if (!hasUnsaved) {\n <button mat-stroked-button (click)=\"addSection()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u7AE0\u8282</span>\n </button>\n }\n </div>\n</rolatech-course-manage-content>\n", styles: [""], dependencies: [{ kind: "component", type: CourseSectionItemComponent, selector: "rolatech-course-section-item", inputs: ["section", "actions", "hasUnsaved", "editId"], outputs: ["sectionChange", "actionsChange", "hasUnsavedChange", "editIdChange", "save", "cancel", "delete", "edit", "addLecture"] }, { kind: "component", type: CourseSectionLectureItemComponent, selector: "rolatech-course-section-lecture-item", inputs: ["progress", "lecture", "actions", "hasUnsaved", "editId"], outputs: ["editIdChange", "save", "cancel", "delete", "edit", "mediaEdit", "thumbnailUpload", "upload", "deleteMedia"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: ToolbarComponent, selector: "rolatech-toolbar", inputs: ["title", "subtitle", "back", "link", "large", "divider"] }, { kind: "component", type: CourseManageContentComponent, selector: "rolatech-course-manage-content" }] }); }
2930
+ }
2931
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageSectionComponent, decorators: [{
2932
+ type: Component,
2933
+ args: [{ selector: 'rolatech-course-manage-section', standalone: true, imports: [
2934
+ CourseSectionItemComponent,
2935
+ CourseSectionLectureItemComponent,
2936
+ MatButtonModule,
2937
+ MatIconModule,
2938
+ MatProgressBarModule,
2939
+ ToolbarComponent,
2940
+ CourseManageContentComponent,
2941
+ ], template: "<rolatech-course-manage-content>\n <rolatech-toolbar title=\"\u7AE0\u8282\" class=\"hidden sm:block\" divider> </rolatech-toolbar>\n <div>\n <div>\n @for (section of sections; track $index) {\n <div class=\"bg-gray-100 p-2 mb-2 rounded-lg\">\n <rolatech-course-section-item\n [section]=\"section\"\n (edit)=\"onSectionEdit($event)\"\n (save)=\"onSectionSave($event)\"\n (delete)=\"onSectionDelete($event)\"\n [editId]=\"editId\"\n >\n <div class=\"bg-white sm:ml-8 mt-3 rounded-md divide-y divide-dashed\">\n @if (section?.lectures) {\n @for (lecture of section.lectures; track $index) {\n <div>\n <rolatech-course-section-lecture-item\n [lecture]=\"lecture\"\n (save)=\"onLectureSave($event)\"\n (delete)=\"onLectureDelete(section, $event)\"\n (edit)=\"onLectureEdit($event)\"\n (upload)=\"onMediaUploadInit(lecture, $event)\"\n (mediaEdit)=\"onMediaEdit(lecture, $event)\"\n (deleteMedia)=\"onMediaDelete(lecture, $event)\"\n [editId]=\"lectureEditId\"\n ></rolatech-course-section-lecture-item>\n </div>\n }\n }\n <div class=\"p-2\">\n <button mat-flat-button (click)=\"addLecture(section)\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u5C0F\u8282</span>\n </button>\n </div>\n </div>\n </rolatech-course-section-item>\n </div>\n }\n </div>\n @if (!hasUnsaved) {\n <button mat-stroked-button (click)=\"addSection()\" class=\"mt-3\">\n <mat-icon>add</mat-icon>\n <span>\u589E\u52A0\u7AE0\u8282</span>\n </button>\n }\n </div>\n</rolatech-course-manage-content>\n" }]
2942
+ }] });
2943
+
2944
+ class CourseManageLayoutComponent {
2945
+ constructor() {
2946
+ this.submitted = false;
2947
+ this.accepted = false;
2948
+ this.isDraft = false;
2949
+ this.route = inject(ActivatedRoute);
2950
+ this.courseService = inject(CourseService);
2951
+ this.dialog = inject(MatDialog);
2952
+ this.snackBar = inject(MatSnackBar);
2953
+ this.id = this.route.parent?.snapshot.paramMap.get('id');
2954
+ }
2955
+ ngOnInit() {
2956
+ this.get();
2957
+ }
2958
+ get() {
2959
+ this.courseService.get(this.id).subscribe({
2960
+ next: (res) => {
2961
+ this.course = res.data;
2962
+ this.updateStatus();
2963
+ },
2964
+ });
2965
+ }
2966
+ updateStatus() {
2967
+ this.isDraft = this.course.status.toString() === 'DRAFT' || this.course.status.toString() === 'PENDING';
2968
+ this.accepted = this.course.status.toString() === 'ACCEPTED';
2969
+ }
2970
+ submitForReview() {
2971
+ this.courseService.review(this.id).subscribe({
2972
+ next: (res) => {
2973
+ this.snackBar.open('提交成功, 等待审核');
2974
+ this.course.status = CourseStatus['审核中'];
2975
+ this.updateStatus();
2976
+ },
2977
+ error: (error) => {
2978
+ this.snackBar.open(error.message);
2979
+ },
2980
+ });
2981
+ }
2982
+ publish() {
2983
+ this.courseService.publish(this.id).subscribe({
2984
+ next: (res) => {
2985
+ this.snackBar.open('发布成功');
2986
+ this.course.status = CourseStatus['已发布'];
2987
+ this.updateStatus();
2988
+ },
2989
+ error: (error) => {
2990
+ this.snackBar.open(error.message);
2991
+ },
2992
+ });
2993
+ }
2994
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2995
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: CourseManageLayoutComponent, isStandalone: true, selector: "rolatech-course-manage-layout", ngImport: i0, template: "<div class=\"flex flex-col md:flex-row m-auto\">\n <div\n class=\"min-w-[256px] px-3 flex flex-row md:flex-col md:h-full items-center md:items-start h-16 overflow-x-scroll overflow-y-hidden scrollbar-hide whitespace-pre\"\n >\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u8BFE\u7A0B\u4FE1\u606F</div>\n <a routerLink=\"./info\" routerLinkActive=\"manage-active\" class=\"p-3\">\u57FA\u672C\u4FE1\u606F</a>\n <a routerLink=\"./media\" routerLinkActive=\"manage-active\" class=\"p-3\">\u56FE\u7247</a>\n <a routerLink=\"./details\" routerLinkActive=\"manage-active\" class=\"p-3\">\u8BE6\u60C5</a>\n </div>\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u8BFE\u7A0B\u5185\u5BB9</div>\n <a routerLink=\"./section\" routerLinkActive=\"manage-active\" class=\"p-3\">\u7AE0\u8282</a>\n <a routerLink=\"./schedule\" routerLinkActive=\"manage-active\" class=\"p-3\">\u8BFE\u8868</a>\n </div>\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u5176\u4ED6\u4FE1\u606F</div>\n <a routerLink=\"./pricing\" routerLinkActive=\"manage-active\" class=\"p-3\">\u4EF7\u683C</a>\n </div>\n\n @if (isDraft) {\n <div class=\"md:mt-6 ml-3 md:ml-2\">\n <!-- <button mat-stroked-button (click)=\"publish()\">\u9884\u89C8</button> -->\n <button mat-flat-button (click)=\"submitForReview()\">\u63D0\u4EA4\u5BA1\u6838</button>\n </div>\n }\n\n @if (accepted) {\n <div class=\"md:mt-6 md:ml-2\">\n <button mat-flat-button color=\"primary\" (click)=\"publish()\">\u53D1\u5E03\u8BFE\u7A0B</button>\n </div>\n }\n </div>\n <div class=\"w-full\">\n <router-outlet></router-outlet>\n </div>\n</div>\n", styles: [".manage-active{background-color:#0000000d;box-shadow:5px 0 #000 inset;font-weight:600}@media (max-width: 768px){.manage-active{box-shadow:inset 0 -4px #000}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
2996
+ }
2997
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CourseManageLayoutComponent, decorators: [{
2998
+ type: Component,
2999
+ args: [{ selector: 'rolatech-course-manage-layout', standalone: true, imports: [RouterLink, RouterLinkActive, MatButtonModule, RouterOutlet, CourseManageContentComponent], template: "<div class=\"flex flex-col md:flex-row m-auto\">\n <div\n class=\"min-w-[256px] px-3 flex flex-row md:flex-col md:h-full items-center md:items-start h-16 overflow-x-scroll overflow-y-hidden scrollbar-hide whitespace-pre\"\n >\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u8BFE\u7A0B\u4FE1\u606F</div>\n <a routerLink=\"./info\" routerLinkActive=\"manage-active\" class=\"p-3\">\u57FA\u672C\u4FE1\u606F</a>\n <a routerLink=\"./media\" routerLinkActive=\"manage-active\" class=\"p-3\">\u56FE\u7247</a>\n <a routerLink=\"./details\" routerLinkActive=\"manage-active\" class=\"p-3\">\u8BE6\u60C5</a>\n </div>\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u8BFE\u7A0B\u5185\u5BB9</div>\n <a routerLink=\"./section\" routerLinkActive=\"manage-active\" class=\"p-3\">\u7AE0\u8282</a>\n <a routerLink=\"./schedule\" routerLinkActive=\"manage-active\" class=\"p-3\">\u8BFE\u8868</a>\n </div>\n <div class=\"flex flex-row md:flex-col md:w-full\">\n <div class=\"hidden md:flex text-xl font-bold h-14 items-center px-2\">\u5176\u4ED6\u4FE1\u606F</div>\n <a routerLink=\"./pricing\" routerLinkActive=\"manage-active\" class=\"p-3\">\u4EF7\u683C</a>\n </div>\n\n @if (isDraft) {\n <div class=\"md:mt-6 ml-3 md:ml-2\">\n <!-- <button mat-stroked-button (click)=\"publish()\">\u9884\u89C8</button> -->\n <button mat-flat-button (click)=\"submitForReview()\">\u63D0\u4EA4\u5BA1\u6838</button>\n </div>\n }\n\n @if (accepted) {\n <div class=\"md:mt-6 md:ml-2\">\n <button mat-flat-button color=\"primary\" (click)=\"publish()\">\u53D1\u5E03\u8BFE\u7A0B</button>\n </div>\n }\n </div>\n <div class=\"w-full\">\n <router-outlet></router-outlet>\n </div>\n</div>\n", styles: [".manage-active{background-color:#0000000d;box-shadow:5px 0 #000 inset;font-weight:600}@media (max-width: 768px){.manage-active{box-shadow:inset 0 -4px #000}}\n"] }]
3000
+ }], ctorParameters: () => [] });
3001
+
3002
+ const courseManageRoutes = [
3003
+ {
3004
+ path: '',
3005
+ component: CourseManageLayoutComponent,
3006
+ children: [
3007
+ {
3008
+ path: 'info',
3009
+ component: CourseManageInfoComponent,
3010
+ },
3011
+ {
3012
+ path: 'media',
3013
+ component: CourseManageMediaComponent,
3014
+ },
3015
+ {
3016
+ path: 'details',
3017
+ component: CourseManageDetailsComponent,
3018
+ },
3019
+ {
3020
+ path: 'pricing',
3021
+ component: CourseManagePricingComponent,
3022
+ },
3023
+ {
3024
+ path: 'schedule',
3025
+ component: CourseManageScheduleComponent,
3026
+ },
3027
+ {
3028
+ path: 'section',
3029
+ component: CourseManageSectionComponent,
3030
+ },
3031
+ ],
3032
+ },
3033
+ ];
3034
+
1953
3035
  /**
1954
3036
  * Generated bundle index. Do not edit.
1955
3037
  */
1956
3038
 
1957
- export { CourseMediaOwnerRendererComponent as A, CourseSectionLectureVideoDialogComponent as B, CourseService as C, ScheduleItemComponent as D, DetailItemComponent as E, courseItem_component as F, PricingItemComponent as P, ScheduleDate as S, CategoryService as a, CourseStatus as b, courseRoutes as c, CourseRequestStatus as d, CourseType as e, CourseReviewStatus as f, CourseSectionLectureContentType as g, CoursePreviewComponent as h, CourseInfoComponent as i, CourseMediaComponent as j, CoursePricingComponent as k, CourseActionComponent as l, CourseScheduleComponent as m, CourseSectionsComponent as n, CourseSectionItemComponent as o, provideAngulaCourse as p, CourseSectionLectureItemComponent as q, CourseSectionLectureVideoItemComponent as r, CourseItemComponent as s, CoursePricingAddDialogComponent as t, CourseScheduleAddDialogComponent as u, CoursePricingDialogComponent as v, CourseScheduleDialogComponent as w, CourseDetailsDialogComponent as x, CourseEditDialogComponent as y, CourseDetailsComponent as z };
1958
- //# sourceMappingURL=rolatech-angular-course-rolatech-angular-course-D-_W2GtF.mjs.map
3039
+ export { CourseDetailsComponent as A, CourseMediaOwnerRendererComponent as B, CourseService as C, CourseSectionLectureVideoDialogComponent as D, ScheduleItemComponent as E, DetailItemComponent as F, courseItem_component as G, PricingItemComponent as P, ScheduleDate as S, CategoryService as a, courseManageRoutes as b, courseRoutes as c, CourseStatus as d, CourseRequestStatus as e, CourseType as f, CourseReviewStatus as g, CourseSectionLectureContentType as h, CoursePreviewComponent as i, CourseInfoComponent as j, CourseMediaComponent as k, CoursePricingComponent as l, CourseActionComponent as m, CourseScheduleComponent as n, CourseSectionsComponent as o, provideAngulaCourse as p, CourseSectionItemComponent as q, CourseSectionLectureItemComponent as r, CourseSectionLectureVideoItemComponent as s, CourseItemComponent as t, CoursePricingAddDialogComponent as u, CourseScheduleAddDialogComponent as v, CoursePricingDialogComponent as w, CourseScheduleDialogComponent as x, CourseDetailsDialogComponent as y, CourseEditDialogComponent as z };
3040
+ //# sourceMappingURL=rolatech-angular-course-rolatech-angular-course-DhmJ0teX.mjs.map