1436 lines
74 KiB
JavaScript
1436 lines
74 KiB
JavaScript
import {
|
|
DefaultValueAccessor,
|
|
FormsModule,
|
|
NgControlStatus,
|
|
NgModel
|
|
} from "./chunk-VD6QIYHN.js";
|
|
import {
|
|
getErrorMessage
|
|
} from "./chunk-QDZ3GX5R.js";
|
|
import {
|
|
CourseService
|
|
} from "./chunk-6K3TDILH.js";
|
|
import {
|
|
NzMessageService
|
|
} from "./chunk-GJYGTZ7J.js";
|
|
import {
|
|
ActivatedRoute,
|
|
ApiService,
|
|
AuthService,
|
|
NzIconDirective,
|
|
NzIconModule,
|
|
Router
|
|
} from "./chunk-2TRRHRR7.js";
|
|
import "./chunk-EDRPZB37.js";
|
|
import {
|
|
Component,
|
|
Injectable,
|
|
forkJoin,
|
|
inject,
|
|
map,
|
|
setClassMetadata,
|
|
signal,
|
|
ɵsetClassDebugInfo,
|
|
ɵɵProvidersFeature,
|
|
ɵɵadvance,
|
|
ɵɵclassProp,
|
|
ɵɵconditional,
|
|
ɵɵconditionalCreate,
|
|
ɵɵdefineComponent,
|
|
ɵɵdefineInjectable,
|
|
ɵɵelement,
|
|
ɵɵelementEnd,
|
|
ɵɵelementStart,
|
|
ɵɵgetCurrentView,
|
|
ɵɵlistener,
|
|
ɵɵnextContext,
|
|
ɵɵproperty,
|
|
ɵɵrepeater,
|
|
ɵɵrepeaterCreate,
|
|
ɵɵrepeaterTrackByIdentity,
|
|
ɵɵresetView,
|
|
ɵɵrestoreView,
|
|
ɵɵtext,
|
|
ɵɵtextInterpolate,
|
|
ɵɵtextInterpolate1
|
|
} from "./chunk-WI7WFVZR.js";
|
|
import {
|
|
__spreadProps,
|
|
__spreadValues
|
|
} from "./chunk-WDMUDEB6.js";
|
|
|
|
// src/app/services/topic.service.ts
|
|
var TopicService = class _TopicService {
|
|
api = inject(ApiService);
|
|
createTopic(courseId, title, description, position) {
|
|
return this.api.post("/api/topics", { courseId, title, description, position });
|
|
}
|
|
updateTopic(id, title, description, position) {
|
|
return this.api.put(`/api/topics/${id}`, { id, title, description, position });
|
|
}
|
|
deleteTopic(id) {
|
|
return this.api.delete(`/api/topics/${id}`);
|
|
}
|
|
linkResource(topicId, resourceId, position) {
|
|
return this.api.post(`/api/topics/${topicId}/resources/${resourceId}`, { position });
|
|
}
|
|
unlinkResource(topicId, resourceId) {
|
|
return this.api.delete(`/api/topics/${topicId}/resources/${resourceId}`);
|
|
}
|
|
static \u0275fac = function TopicService_Factory(__ngFactoryType__) {
|
|
return new (__ngFactoryType__ || _TopicService)();
|
|
};
|
|
static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _TopicService, factory: _TopicService.\u0275fac, providedIn: "root" });
|
|
};
|
|
(() => {
|
|
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(TopicService, [{
|
|
type: Injectable,
|
|
args: [{
|
|
providedIn: "root"
|
|
}]
|
|
}], null, null);
|
|
})();
|
|
|
|
// src/app/services/resource.service.ts
|
|
var TYPE_TO_INT = {
|
|
"Url": 0,
|
|
"Video": 1,
|
|
"Text": 2,
|
|
"File": 3
|
|
};
|
|
var INT_TO_TYPE = {
|
|
0: "Url",
|
|
1: "Video",
|
|
2: "Text",
|
|
3: "File"
|
|
};
|
|
function normalizeResource(r) {
|
|
return __spreadProps(__spreadValues({}, r), {
|
|
type: typeof r.type === "number" ? INT_TO_TYPE[r.type] ?? "Url" : r.type
|
|
});
|
|
}
|
|
var ResourceService = class _ResourceService {
|
|
api = inject(ApiService);
|
|
getResources() {
|
|
return this.api.get("/api/resources").pipe(map((list) => list.map(normalizeResource)));
|
|
}
|
|
createResource(type, title, content) {
|
|
return this.api.post("/api/resources", { type: TYPE_TO_INT[type], title, content }).pipe(map(normalizeResource));
|
|
}
|
|
updateResource(id, type, title, content) {
|
|
return this.api.put(`/api/resources/${id}`, { id, type: TYPE_TO_INT[type], title, content }).pipe(map(normalizeResource));
|
|
}
|
|
deleteResource(id) {
|
|
return this.api.delete(`/api/resources/${id}`);
|
|
}
|
|
static \u0275fac = function ResourceService_Factory(__ngFactoryType__) {
|
|
return new (__ngFactoryType__ || _ResourceService)();
|
|
};
|
|
static \u0275prov = /* @__PURE__ */ \u0275\u0275defineInjectable({ token: _ResourceService, factory: _ResourceService.\u0275fac, providedIn: "root" });
|
|
};
|
|
(() => {
|
|
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ResourceService, [{
|
|
type: Injectable,
|
|
args: [{
|
|
providedIn: "root"
|
|
}]
|
|
}], null, null);
|
|
})();
|
|
|
|
// src/app/pages/course-editor/course-editor.ts
|
|
var _forTrack0 = ($index, $item) => $item.id;
|
|
function CourseEditorPage_Conditional_1_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 1);
|
|
\u0275\u0275element(1, "span", 2);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_20_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Enregistrement... ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_21_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0);
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275textInterpolate1(" ", ctx_r1.isEditMode() ? "Enregistrer les modifications" : "Cr\xE9er le cours", " ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_7_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "p", 19);
|
|
\u0275\u0275text(1, "Aucun sujet. Commencez par en ajouter un.");
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Conditional_16_For_2_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r6 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 38);
|
|
\u0275\u0275element(1, "span", 39);
|
|
\u0275\u0275elementStart(2, "span", 40);
|
|
\u0275\u0275text(3);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "button", 41);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Conditional_16_For_2_Template_button_click_4_listener($event) {
|
|
const resource_r7 = \u0275\u0275restoreView(_r6).$implicit;
|
|
const topic_r5 = \u0275\u0275nextContext(2).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(5);
|
|
return \u0275\u0275resetView(ctx_r1.unlinkResource(topic_r5, resource_r7, $event));
|
|
});
|
|
\u0275\u0275element(5, "span", 42);
|
|
\u0275\u0275elementEnd()();
|
|
}
|
|
if (rf & 2) {
|
|
const resource_r7 = ctx.$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(7);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275property("nzType", ctx_r1.getResourceIcon(resource_r7.type));
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275textInterpolate(resource_r7.title);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Conditional_16_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 37);
|
|
\u0275\u0275repeaterCreate(1, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Conditional_16_For_2_Template, 6, 2, "div", 38, _forTrack0);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const topic_r5 = \u0275\u0275nextContext().$implicit;
|
|
\u0275\u0275advance();
|
|
\u0275\u0275repeater(topic_r5.resources);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r4 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 25)(1, "div", 26)(2, "div", 27);
|
|
\u0275\u0275text(3);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "div", 28)(5, "p", 29);
|
|
\u0275\u0275text(6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(7, "span", 30);
|
|
\u0275\u0275text(8);
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(9, "div", 31)(10, "button", 32);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Template_button_click_10_listener($event) {
|
|
const topic_r5 = \u0275\u0275restoreView(_r4).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(5);
|
|
return \u0275\u0275resetView(ctx_r1.openLinkResource(topic_r5, $event));
|
|
});
|
|
\u0275\u0275element(11, "span", 33);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(12, "button", 34);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Template_button_click_12_listener($event) {
|
|
const topic_r5 = \u0275\u0275restoreView(_r4).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(5);
|
|
return \u0275\u0275resetView(ctx_r1.openEditTopic(topic_r5, $event));
|
|
});
|
|
\u0275\u0275element(13, "span", 35);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(14, "button", 36);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Template_button_click_14_listener($event) {
|
|
const topic_r5 = \u0275\u0275restoreView(_r4).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(5);
|
|
return \u0275\u0275resetView(ctx_r1.deleteTopic(topic_r5, $event));
|
|
});
|
|
\u0275\u0275element(15, "span", 24);
|
|
\u0275\u0275elementEnd()()();
|
|
\u0275\u0275conditionalCreate(16, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Conditional_16_Template, 3, 0, "div", 37);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const topic_r5 = ctx.$implicit;
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275textInterpolate(topic_r5.position);
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275textInterpolate(topic_r5.title);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275textInterpolate1("", topic_r5.resources.length, " ressource(s)");
|
|
\u0275\u0275advance(8);
|
|
\u0275\u0275conditional(topic_r5.resources.length > 0 ? 16 : -1);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275repeaterCreate(0, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_For_1_Template, 17, 4, "div", 25, _forTrack0);
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
\u0275\u0275repeater(ctx_r1.course().topics);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_16_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "p", 19);
|
|
\u0275\u0275text(1, "Cr\xE9ez des ressources pour les lier aux sujets.");
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_17_For_1_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 25)(1, "div", 26)(2, "div", 43);
|
|
\u0275\u0275element(3, "span", 39);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "div", 28)(5, "p", 29);
|
|
\u0275\u0275text(6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(7, "span", 30);
|
|
\u0275\u0275text(8);
|
|
\u0275\u0275elementEnd()()()();
|
|
}
|
|
if (rf & 2) {
|
|
const resource_r8 = ctx.$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(5);
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275property("nzType", ctx_r1.getResourceIcon(resource_r8.type));
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275textInterpolate(resource_r8.title);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275textInterpolate(resource_r8.type);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_17_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275repeaterCreate(0, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_17_For_1_Template, 9, 3, "div", 25, _forTrack0);
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
\u0275\u0275repeater(ctx_r1.allResources());
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Conditional_1_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Publication... ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Conditional_2_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Publier le cours ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r9 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "button", 44);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Template_button_click_0_listener() {
|
|
\u0275\u0275restoreView(_r9);
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
return \u0275\u0275resetView(ctx_r1.publishCourse());
|
|
});
|
|
\u0275\u0275conditionalCreate(1, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Conditional_1_Template, 1, 0)(2, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Conditional_2_Template, 1, 0);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
\u0275\u0275property("disabled", ctx_r1.publishing());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.publishing() ? 1 : 2);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_20_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 22);
|
|
\u0275\u0275text(1, "Cours publi\xE9");
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r3 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 9)(1, "div", 16)(2, "h2", 10);
|
|
\u0275\u0275text(3);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "button", 17);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Template_button_click_4_listener() {
|
|
\u0275\u0275restoreView(_r3);
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.openAddTopic());
|
|
});
|
|
\u0275\u0275element(5, "span", 18);
|
|
\u0275\u0275text(6, " Ajouter ");
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275conditionalCreate(7, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_7_Template, 2, 0, "p", 19)(8, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_8_Template, 2, 0);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(9, "div", 9)(10, "div", 16)(11, "h2", 10);
|
|
\u0275\u0275text(12);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(13, "button", 17);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Template_button_click_13_listener() {
|
|
\u0275\u0275restoreView(_r3);
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.openAddResource());
|
|
});
|
|
\u0275\u0275element(14, "span", 18);
|
|
\u0275\u0275text(15, " Nouvelle ");
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275conditionalCreate(16, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_16_Template, 2, 0, "p", 19)(17, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_17_Template, 2, 0);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(18, "div", 20);
|
|
\u0275\u0275conditionalCreate(19, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_19_Template, 3, 2, "button", 21)(20, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Conditional_20_Template, 2, 0, "div", 22);
|
|
\u0275\u0275elementStart(21, "button", 23);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Template_button_click_21_listener() {
|
|
\u0275\u0275restoreView(_r3);
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.deleteCourse());
|
|
});
|
|
\u0275\u0275element(22, "span", 24);
|
|
\u0275\u0275text(23, " Supprimer le cours ");
|
|
\u0275\u0275elementEnd()();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275textInterpolate1("Sujets (", ctx_r1.course().topics.length, ")");
|
|
\u0275\u0275advance(4);
|
|
\u0275\u0275conditional(ctx_r1.course().topics.length === 0 ? 7 : 8);
|
|
\u0275\u0275advance(5);
|
|
\u0275\u0275textInterpolate1("Ressources (", ctx_r1.allResources().length, ")");
|
|
\u0275\u0275advance(4);
|
|
\u0275\u0275conditional(ctx_r1.allResources().length === 0 ? 16 : 17);
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275conditional(ctx_r1.course().status === "Draft" ? 19 : 20);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_0_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r1 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 3)(1, "div", 4)(2, "button", 5);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Template_button_click_2_listener() {
|
|
\u0275\u0275restoreView(_r1);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.goBack());
|
|
});
|
|
\u0275\u0275element(3, "span", 6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "h1", 7);
|
|
\u0275\u0275text(5);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275element(6, "div");
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(7, "div", 8)(8, "div", 9)(9, "h2", 10);
|
|
\u0275\u0275text(10, "Informations");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(11, "div", 11)(12, "label", 12);
|
|
\u0275\u0275text(13, "Titre du cours");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(14, "input", 13);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_0_Template_input_ngModelChange_14_listener($event) {
|
|
\u0275\u0275restoreView(_r1);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.courseTitle.set($event));
|
|
});
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(15, "div", 11)(16, "label", 12);
|
|
\u0275\u0275text(17, "Description");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(18, "textarea", 14);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_0_Template_textarea_ngModelChange_18_listener($event) {
|
|
\u0275\u0275restoreView(_r1);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.courseDescription.set($event));
|
|
});
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(19, "button", 15);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_0_Template_button_click_19_listener() {
|
|
\u0275\u0275restoreView(_r1);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.saveCourse());
|
|
});
|
|
\u0275\u0275conditionalCreate(20, CourseEditorPage_Conditional_2_Conditional_0_Conditional_20_Template, 1, 0)(21, CourseEditorPage_Conditional_2_Conditional_0_Conditional_21_Template, 1, 1);
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275conditionalCreate(22, CourseEditorPage_Conditional_2_Conditional_0_Conditional_22_Template, 24, 5);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
\u0275\u0275advance(5);
|
|
\u0275\u0275textInterpolate1(" ", ctx_r1.isEditMode() ? "Modifier le cours" : "Nouveau cours", " ");
|
|
\u0275\u0275advance(9);
|
|
\u0275\u0275property("ngModel", ctx_r1.courseTitle());
|
|
\u0275\u0275advance(4);
|
|
\u0275\u0275property("ngModel", ctx_r1.courseDescription());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275property("disabled", ctx_r1.saving());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.saving() ? 20 : 21);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275conditional(ctx_r1.isEditMode() && ctx_r1.course() ? 22 : -1);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_1_Conditional_18_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Enregistrement... ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_1_Conditional_19_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0);
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275textInterpolate1(" ", ctx_r1.editingTopicId() ? "Mettre \xE0 jour" : "Ajouter le sujet", " ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_1_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r10 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 3)(1, "div", 4)(2, "button", 5);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_1_Template_button_click_2_listener() {
|
|
\u0275\u0275restoreView(_r10);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.cancelMode());
|
|
});
|
|
\u0275\u0275element(3, "span", 6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "h1", 7);
|
|
\u0275\u0275text(5);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275element(6, "div");
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(7, "div", 8)(8, "div", 9)(9, "div", 11)(10, "label", 12);
|
|
\u0275\u0275text(11, "Titre du sujet");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(12, "input", 45);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_1_Template_input_ngModelChange_12_listener($event) {
|
|
\u0275\u0275restoreView(_r10);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.topicTitle.set($event));
|
|
});
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(13, "div", 11)(14, "label", 12);
|
|
\u0275\u0275text(15, "Description (optionnel)");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(16, "textarea", 46);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_1_Template_textarea_ngModelChange_16_listener($event) {
|
|
\u0275\u0275restoreView(_r10);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.topicDescription.set($event));
|
|
});
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(17, "button", 15);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_1_Template_button_click_17_listener() {
|
|
\u0275\u0275restoreView(_r10);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.saveTopic());
|
|
});
|
|
\u0275\u0275conditionalCreate(18, CourseEditorPage_Conditional_2_Conditional_1_Conditional_18_Template, 1, 0)(19, CourseEditorPage_Conditional_2_Conditional_1_Conditional_19_Template, 1, 1);
|
|
\u0275\u0275elementEnd()()();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
\u0275\u0275advance(5);
|
|
\u0275\u0275textInterpolate1(" ", ctx_r1.editingTopicId() ? "Modifier le sujet" : "Nouveau sujet", " ");
|
|
\u0275\u0275advance(7);
|
|
\u0275\u0275property("ngModel", ctx_r1.topicTitle());
|
|
\u0275\u0275advance(4);
|
|
\u0275\u0275property("ngModel", ctx_r1.topicDescription());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275property("disabled", ctx_r1.saving());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.saving() ? 18 : 19);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_For_14_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r12 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "button", 52);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_2_For_14_Template_button_click_0_listener() {
|
|
const type_r13 = \u0275\u0275restoreView(_r12).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.resourceType.set(type_r13));
|
|
});
|
|
\u0275\u0275element(1, "span", 39);
|
|
\u0275\u0275text(2);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const type_r13 = ctx.$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275classProp("active", ctx_r1.resourceType() === type_r13);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275property("nzType", ctx_r1.getResourceIcon(type_r13));
|
|
\u0275\u0275advance();
|
|
\u0275\u0275textInterpolate1(" ", type_r13, " ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_21_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Contenu (texte/markdown) ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_22_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Chemin ou URL du fichier ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_23_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " URL ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_24_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r14 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "textarea", 53);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_2_Conditional_24_Template_textarea_ngModelChange_0_listener($event) {
|
|
\u0275\u0275restoreView(_r14);
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.resourceContent.set($event));
|
|
});
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275property("ngModel", ctx_r1.resourceContent());
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_25_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r15 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "input", 54);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_2_Conditional_25_Template_input_ngModelChange_0_listener($event) {
|
|
\u0275\u0275restoreView(_r15);
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
return \u0275\u0275resetView(ctx_r1.resourceContent.set($event));
|
|
});
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275property("ngModel", ctx_r1.resourceContent());
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_27_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Enregistrement... ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Conditional_28_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275text(0, " Cr\xE9er la ressource ");
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_2_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r11 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 3)(1, "div", 4)(2, "button", 5);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_2_Template_button_click_2_listener() {
|
|
\u0275\u0275restoreView(_r11);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.cancelMode());
|
|
});
|
|
\u0275\u0275element(3, "span", 6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "h1", 7);
|
|
\u0275\u0275text(5, "Nouvelle ressource");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275element(6, "div");
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(7, "div", 8)(8, "div", 9)(9, "div", 11)(10, "label", 12);
|
|
\u0275\u0275text(11, "Type");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(12, "div", 47);
|
|
\u0275\u0275repeaterCreate(13, CourseEditorPage_Conditional_2_Conditional_2_For_14_Template, 3, 4, "button", 48, \u0275\u0275repeaterTrackByIdentity);
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(15, "div", 11)(16, "label", 12);
|
|
\u0275\u0275text(17, "Titre");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(18, "input", 49);
|
|
\u0275\u0275listener("ngModelChange", function CourseEditorPage_Conditional_2_Conditional_2_Template_input_ngModelChange_18_listener($event) {
|
|
\u0275\u0275restoreView(_r11);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.resourceTitle.set($event));
|
|
});
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275elementStart(19, "div", 11)(20, "label", 12);
|
|
\u0275\u0275conditionalCreate(21, CourseEditorPage_Conditional_2_Conditional_2_Conditional_21_Template, 1, 0)(22, CourseEditorPage_Conditional_2_Conditional_2_Conditional_22_Template, 1, 0)(23, CourseEditorPage_Conditional_2_Conditional_2_Conditional_23_Template, 1, 0);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275conditionalCreate(24, CourseEditorPage_Conditional_2_Conditional_2_Conditional_24_Template, 1, 1, "textarea", 50)(25, CourseEditorPage_Conditional_2_Conditional_2_Conditional_25_Template, 1, 1, "input", 51);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(26, "button", 15);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_2_Template_button_click_26_listener() {
|
|
\u0275\u0275restoreView(_r11);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.saveResource());
|
|
});
|
|
\u0275\u0275conditionalCreate(27, CourseEditorPage_Conditional_2_Conditional_2_Conditional_27_Template, 1, 0)(28, CourseEditorPage_Conditional_2_Conditional_2_Conditional_28_Template, 1, 0);
|
|
\u0275\u0275elementEnd()()();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
\u0275\u0275advance(13);
|
|
\u0275\u0275repeater(ctx_r1.resourceTypes);
|
|
\u0275\u0275advance(5);
|
|
\u0275\u0275property("ngModel", ctx_r1.resourceTitle());
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275conditional(ctx_r1.resourceType() === "Text" ? 21 : ctx_r1.resourceType() === "File" ? 22 : 23);
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275conditional(ctx_r1.resourceType() === "Text" ? 24 : 25);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275property("disabled", ctx_r1.saving());
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.saving() ? 27 : 28);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_3_Conditional_12_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 9)(1, "p", 19);
|
|
\u0275\u0275text(2, "Aucune ressource disponible. Cr\xE9ez-en une d'abord.");
|
|
\u0275\u0275elementEnd()();
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_For_2_Conditional_8_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275element(0, "span", 62);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_For_2_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r17 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 58);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_For_2_Template_div_click_0_listener() {
|
|
const resource_r18 = \u0275\u0275restoreView(_r17).$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
return \u0275\u0275resetView(!ctx_r1.isResourceLinked(resource_r18) && ctx_r1.linkResource(resource_r18));
|
|
});
|
|
\u0275\u0275elementStart(1, "div", 43);
|
|
\u0275\u0275element(2, "span", 39);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(3, "div", 59)(4, "p", 60);
|
|
\u0275\u0275text(5);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(6, "span", 61);
|
|
\u0275\u0275text(7);
|
|
\u0275\u0275elementEnd()();
|
|
\u0275\u0275conditionalCreate(8, CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_For_2_Conditional_8_Template, 1, 0, "span", 62);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const resource_r18 = ctx.$implicit;
|
|
const ctx_r1 = \u0275\u0275nextContext(4);
|
|
\u0275\u0275classProp("linked", ctx_r1.isResourceLinked(resource_r18));
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275property("nzType", ctx_r1.getResourceIcon(resource_r18.type));
|
|
\u0275\u0275advance(3);
|
|
\u0275\u0275textInterpolate(resource_r18.title);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275textInterpolate(resource_r18.type);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.isResourceLinked(resource_r18) ? 8 : -1);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 56);
|
|
\u0275\u0275repeaterCreate(1, CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_For_2_Template, 9, 6, "div", 57, _forTrack0);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext(3);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275repeater(ctx_r1.allResources());
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Conditional_3_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
const _r16 = \u0275\u0275getCurrentView();
|
|
\u0275\u0275elementStart(0, "div", 3)(1, "div", 4)(2, "button", 5);
|
|
\u0275\u0275listener("click", function CourseEditorPage_Conditional_2_Conditional_3_Template_button_click_2_listener() {
|
|
\u0275\u0275restoreView(_r16);
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
return \u0275\u0275resetView(ctx_r1.cancelMode());
|
|
});
|
|
\u0275\u0275element(3, "span", 6);
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(4, "h1", 7);
|
|
\u0275\u0275text(5, "Lier une ressource");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275element(6, "div");
|
|
\u0275\u0275elementEnd();
|
|
\u0275\u0275elementStart(7, "p", 55);
|
|
\u0275\u0275text(8, "Sujet : ");
|
|
\u0275\u0275elementStart(9, "strong");
|
|
\u0275\u0275text(10);
|
|
\u0275\u0275elementEnd()()();
|
|
\u0275\u0275elementStart(11, "div", 8);
|
|
\u0275\u0275conditionalCreate(12, CourseEditorPage_Conditional_2_Conditional_3_Conditional_12_Template, 3, 0, "div", 9)(13, CourseEditorPage_Conditional_2_Conditional_3_Conditional_13_Template, 3, 0, "div", 56);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
let tmp_2_0;
|
|
const ctx_r1 = \u0275\u0275nextContext(2);
|
|
\u0275\u0275advance(10);
|
|
\u0275\u0275textInterpolate((tmp_2_0 = ctx_r1.selectedTopic()) == null ? null : tmp_2_0.title);
|
|
\u0275\u0275advance(2);
|
|
\u0275\u0275conditional(ctx_r1.allResources().length === 0 ? 12 : 13);
|
|
}
|
|
}
|
|
function CourseEditorPage_Conditional_2_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275conditionalCreate(0, CourseEditorPage_Conditional_2_Conditional_0_Template, 23, 6);
|
|
\u0275\u0275conditionalCreate(1, CourseEditorPage_Conditional_2_Conditional_1_Template, 20, 5);
|
|
\u0275\u0275conditionalCreate(2, CourseEditorPage_Conditional_2_Conditional_2_Template, 29, 5);
|
|
\u0275\u0275conditionalCreate(3, CourseEditorPage_Conditional_2_Conditional_3_Template, 14, 2);
|
|
}
|
|
if (rf & 2) {
|
|
const ctx_r1 = \u0275\u0275nextContext();
|
|
\u0275\u0275conditional(ctx_r1.mode() === "course" ? 0 : -1);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.mode() === "topic" ? 1 : -1);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.mode() === "resource" ? 2 : -1);
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx_r1.mode() === "link-resource" ? 3 : -1);
|
|
}
|
|
}
|
|
var CourseEditorPage = class _CourseEditorPage {
|
|
route = inject(ActivatedRoute);
|
|
router = inject(Router);
|
|
courseService = inject(CourseService);
|
|
topicService = inject(TopicService);
|
|
resourceService = inject(ResourceService);
|
|
authService = inject(AuthService);
|
|
message = inject(NzMessageService);
|
|
// State
|
|
isEditMode = signal(false, ...ngDevMode ? [{ debugName: "isEditMode" }] : []);
|
|
loading = signal(true, ...ngDevMode ? [{ debugName: "loading" }] : []);
|
|
saving = signal(false, ...ngDevMode ? [{ debugName: "saving" }] : []);
|
|
publishing = signal(false, ...ngDevMode ? [{ debugName: "publishing" }] : []);
|
|
mode = signal("course", ...ngDevMode ? [{ debugName: "mode" }] : []);
|
|
course = signal(null, ...ngDevMode ? [{ debugName: "course" }] : []);
|
|
allResources = signal([], ...ngDevMode ? [{ debugName: "allResources" }] : []);
|
|
selectedTopic = signal(null, ...ngDevMode ? [{ debugName: "selectedTopic" }] : []);
|
|
// Course form
|
|
courseTitle = signal("", ...ngDevMode ? [{ debugName: "courseTitle" }] : []);
|
|
courseDescription = signal("", ...ngDevMode ? [{ debugName: "courseDescription" }] : []);
|
|
// Topic form
|
|
topicTitle = signal("", ...ngDevMode ? [{ debugName: "topicTitle" }] : []);
|
|
topicDescription = signal("", ...ngDevMode ? [{ debugName: "topicDescription" }] : []);
|
|
editingTopicId = signal(null, ...ngDevMode ? [{ debugName: "editingTopicId" }] : []);
|
|
// Resource form
|
|
resourceType = signal("Url", ...ngDevMode ? [{ debugName: "resourceType" }] : []);
|
|
resourceTitle = signal("", ...ngDevMode ? [{ debugName: "resourceTitle" }] : []);
|
|
resourceContent = signal("", ...ngDevMode ? [{ debugName: "resourceContent" }] : []);
|
|
editingResourceId = signal(null, ...ngDevMode ? [{ debugName: "editingResourceId" }] : []);
|
|
resourceTypes = ["Url", "Video", "Text", "File"];
|
|
get currentUser() {
|
|
return this.authService.currentUser();
|
|
}
|
|
ngOnInit() {
|
|
const id = this.route.snapshot.paramMap.get("id");
|
|
if (id) {
|
|
this.isEditMode.set(true);
|
|
this.loadCourse(id);
|
|
} else {
|
|
this.loading.set(false);
|
|
}
|
|
}
|
|
loadCourse(id) {
|
|
this.loading.set(true);
|
|
forkJoin([
|
|
this.courseService.getCourseById(id),
|
|
this.resourceService.getResources()
|
|
]).subscribe({
|
|
next: ([course, resources]) => {
|
|
this.course.set(course);
|
|
this.courseTitle.set(course.title);
|
|
this.courseDescription.set(course.description);
|
|
this.allResources.set(resources);
|
|
this.loading.set(false);
|
|
},
|
|
error: () => {
|
|
this.loading.set(false);
|
|
this.message.error("Cours introuvable");
|
|
this.router.navigate(["/catalog"]);
|
|
}
|
|
});
|
|
}
|
|
// -- Course actions --
|
|
saveCourse() {
|
|
if (!this.courseTitle().trim()) {
|
|
this.message.warning("Le titre est requis");
|
|
return;
|
|
}
|
|
this.saving.set(true);
|
|
const user = this.currentUser;
|
|
if (this.isEditMode()) {
|
|
const id = this.course().id;
|
|
this.courseService.updateCourse(id, this.courseTitle(), this.courseDescription()).subscribe({
|
|
next: (updated) => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), { title: updated.title, description: updated.description }) : c);
|
|
this.saving.set(false);
|
|
this.message.success("Cours mis \xE0 jour");
|
|
},
|
|
error: () => {
|
|
this.saving.set(false);
|
|
this.message.error("Erreur lors de la mise \xE0 jour");
|
|
}
|
|
});
|
|
} else {
|
|
if (!user)
|
|
return;
|
|
this.courseService.createCourse(this.courseTitle(), this.courseDescription(), user.userId).subscribe({
|
|
next: (created) => {
|
|
this.saving.set(false);
|
|
this.message.success("Cours cr\xE9\xE9 !");
|
|
this.router.navigate(["/courses", created.id, "edit"]);
|
|
},
|
|
error: (err) => {
|
|
this.saving.set(false);
|
|
this.message.error(getErrorMessage(err, "Erreur lors de la cr\xE9ation"));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
publishCourse() {
|
|
const course = this.course();
|
|
if (!course)
|
|
return;
|
|
this.publishing.set(true);
|
|
this.courseService.publishCourse(course.id).subscribe({
|
|
next: (updated) => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), { status: updated.status }) : c);
|
|
this.publishing.set(false);
|
|
this.message.success("Cours publi\xE9 !");
|
|
},
|
|
error: (err) => {
|
|
this.publishing.set(false);
|
|
this.message.error(getErrorMessage(err, "Impossible de publier le cours"));
|
|
}
|
|
});
|
|
}
|
|
deleteCourse() {
|
|
const course = this.course();
|
|
if (!course)
|
|
return;
|
|
this.courseService.deleteCourse(course.id).subscribe({
|
|
next: () => {
|
|
this.message.success("Cours supprim\xE9");
|
|
this.router.navigate(["/catalog"]);
|
|
},
|
|
error: (err) => {
|
|
this.message.error(getErrorMessage(err, "Impossible de supprimer le cours"));
|
|
}
|
|
});
|
|
}
|
|
// -- Topic actions --
|
|
openAddTopic() {
|
|
this.topicTitle.set("");
|
|
this.topicDescription.set("");
|
|
this.editingTopicId.set(null);
|
|
this.mode.set("topic");
|
|
}
|
|
openEditTopic(topic, event) {
|
|
event.stopPropagation();
|
|
this.topicTitle.set(topic.title);
|
|
this.topicDescription.set(topic.description ?? "");
|
|
this.editingTopicId.set(topic.id);
|
|
this.mode.set("topic");
|
|
}
|
|
saveTopic() {
|
|
if (!this.topicTitle().trim()) {
|
|
this.message.warning("Le titre du sujet est requis");
|
|
return;
|
|
}
|
|
const course = this.course();
|
|
if (!course)
|
|
return;
|
|
this.saving.set(true);
|
|
const editId = this.editingTopicId();
|
|
if (editId) {
|
|
const existing = course.topics.find((t) => t.id === editId);
|
|
this.topicService.updateTopic(editId, this.topicTitle(), this.topicDescription(), existing.position).subscribe({
|
|
next: (updated) => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), {
|
|
topics: c.topics.map((t) => t.id === editId ? __spreadValues(__spreadValues({}, t), updated) : t)
|
|
}) : c);
|
|
this.saving.set(false);
|
|
this.mode.set("course");
|
|
this.message.success("Sujet mis \xE0 jour");
|
|
},
|
|
error: () => {
|
|
this.saving.set(false);
|
|
this.message.error("Erreur lors de la mise \xE0 jour");
|
|
}
|
|
});
|
|
} else {
|
|
const position = course.topics.length + 1;
|
|
const desc = this.topicDescription().trim() || null;
|
|
this.topicService.createTopic(course.id, this.topicTitle(), desc, position).subscribe({
|
|
next: (created) => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), {
|
|
topics: [...c.topics, __spreadProps(__spreadValues({}, created), { resources: [] })],
|
|
topicCount: c.topicCount + 1
|
|
}) : c);
|
|
this.saving.set(false);
|
|
this.mode.set("course");
|
|
this.message.success("Sujet ajout\xE9");
|
|
},
|
|
error: (err) => {
|
|
this.saving.set(false);
|
|
this.message.error(getErrorMessage(err, "Erreur lors de la cr\xE9ation du sujet"));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
deleteTopic(topic, event) {
|
|
event.stopPropagation();
|
|
this.topicService.deleteTopic(topic.id).subscribe({
|
|
next: () => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), {
|
|
topics: c.topics.filter((t) => t.id !== topic.id),
|
|
topicCount: c.topicCount - 1
|
|
}) : c);
|
|
this.message.success("Sujet supprim\xE9");
|
|
},
|
|
error: () => this.message.error("Impossible de supprimer ce sujet")
|
|
});
|
|
}
|
|
// -- Resource actions --
|
|
openAddResource() {
|
|
this.resourceType.set("Url");
|
|
this.resourceTitle.set("");
|
|
this.resourceContent.set("");
|
|
this.editingResourceId.set(null);
|
|
this.mode.set("resource");
|
|
}
|
|
openLinkResource(topic, event) {
|
|
event.stopPropagation();
|
|
this.selectedTopic.set(topic);
|
|
this.resourceService.getResources().subscribe({
|
|
next: (resources) => {
|
|
this.allResources.set(resources);
|
|
this.mode.set("link-resource");
|
|
},
|
|
error: () => this.message.error("Impossible de charger les ressources")
|
|
});
|
|
}
|
|
saveResource() {
|
|
if (!this.resourceTitle().trim() || !this.resourceContent().trim()) {
|
|
this.message.warning("Titre et contenu sont requis");
|
|
return;
|
|
}
|
|
this.saving.set(true);
|
|
this.resourceService.createResource(this.resourceType(), this.resourceTitle(), this.resourceContent()).subscribe({
|
|
next: (created) => {
|
|
this.allResources.update((list) => [...list, created]);
|
|
this.saving.set(false);
|
|
this.mode.set("course");
|
|
this.message.success("Ressource cr\xE9\xE9e");
|
|
},
|
|
error: (err) => {
|
|
this.saving.set(false);
|
|
this.message.error(getErrorMessage(err, "Erreur lors de la cr\xE9ation de la ressource"));
|
|
}
|
|
});
|
|
}
|
|
linkResource(resource) {
|
|
const topic = this.selectedTopic();
|
|
if (!topic)
|
|
return;
|
|
const position = topic.resources.length + 1;
|
|
this.topicService.linkResource(topic.id, resource.id, position).subscribe({
|
|
next: () => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), {
|
|
topics: c.topics.map((t) => t.id === topic.id ? __spreadProps(__spreadValues({}, t), { resources: [...t.resources, resource] }) : t)
|
|
}) : c);
|
|
this.selectedTopic.update((t) => t ? __spreadProps(__spreadValues({}, t), { resources: [...t.resources, resource] }) : t);
|
|
this.message.success("Ressource li\xE9e");
|
|
},
|
|
error: () => this.message.error("Erreur lors de la liaison")
|
|
});
|
|
}
|
|
unlinkResource(topic, resource, event) {
|
|
event.stopPropagation();
|
|
this.topicService.unlinkResource(topic.id, resource.id).subscribe({
|
|
next: () => {
|
|
this.course.update((c) => c ? __spreadProps(__spreadValues({}, c), {
|
|
topics: c.topics.map((t) => t.id === topic.id ? __spreadProps(__spreadValues({}, t), { resources: t.resources.filter((r) => r.id !== resource.id) }) : t)
|
|
}) : c);
|
|
this.message.success("Ressource retir\xE9e");
|
|
},
|
|
error: () => this.message.error("Erreur lors du retrait")
|
|
});
|
|
}
|
|
isResourceLinked(resource) {
|
|
return this.selectedTopic()?.resources.some((r) => r.id === resource.id) ?? false;
|
|
}
|
|
getResourceIcon(type) {
|
|
switch (type) {
|
|
case "Video":
|
|
return "video-camera";
|
|
case "Text":
|
|
return "file-text";
|
|
case "File":
|
|
return "file";
|
|
default:
|
|
return "link";
|
|
}
|
|
}
|
|
cancelMode() {
|
|
this.mode.set("course");
|
|
}
|
|
goBack() {
|
|
this.router.navigate(["/catalog"]);
|
|
}
|
|
static \u0275fac = function CourseEditorPage_Factory(__ngFactoryType__) {
|
|
return new (__ngFactoryType__ || _CourseEditorPage)();
|
|
};
|
|
static \u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _CourseEditorPage, selectors: [["app-course-editor"]], features: [\u0275\u0275ProvidersFeature([NzMessageService])], decls: 3, vars: 1, consts: [[1, "page-container", "editor-page"], [1, "loading-screen"], ["nz-icon", "", "nzType", "loading", "nzTheme", "outline", 1, "loading-spin"], [1, "editor-header"], [1, "header-row"], [1, "back-btn", 3, "click"], ["nz-icon", "", "nzType", "arrow-left", "nzTheme", "outline"], [1, "page-title"], [1, "editor-content"], [1, "section-card"], [1, "section-label"], [1, "field-group"], [1, "field-label"], ["type", "text", "placeholder", "Ex: Introduction \xE0 Angular", 1, "mc-input", 3, "ngModelChange", "ngModel"], ["placeholder", "D\xE9crivez votre cours...", "rows", "4", 1, "mc-input", "mc-textarea", 3, "ngModelChange", "ngModel"], [1, "mc-btn-primary", 3, "click", "disabled"], [1, "section-header"], [1, "add-btn", 3, "click"], ["nz-icon", "", "nzType", "plus", "nzTheme", "outline"], [1, "empty-hint"], [1, "section-card", "danger-zone"], [1, "publish-btn", 3, "disabled"], [1, "status-badge", "published"], [1, "delete-btn", 3, "click"], ["nz-icon", "", "nzType", "delete", "nzTheme", "outline"], [1, "topic-item"], [1, "topic-item-header"], [1, "topic-position"], [1, "topic-item-info"], [1, "topic-item-title"], [1, "topic-item-resources"], [1, "topic-item-actions"], ["title", "Lier une ressource", 1, "icon-action", 3, "click"], ["nz-icon", "", "nzType", "link", "nzTheme", "outline"], ["title", "Modifier", 1, "icon-action", 3, "click"], ["nz-icon", "", "nzType", "edit", "nzTheme", "outline"], ["title", "Supprimer", 1, "icon-action", "danger", 3, "click"], [1, "topic-resources"], [1, "resource-chip"], ["nz-icon", "", "nzTheme", "outline", 3, "nzType"], [1, "chip-title"], [1, "chip-remove", 3, "click"], ["nz-icon", "", "nzType", "close", "nzTheme", "outline"], [1, "resource-icon-sm"], [1, "publish-btn", 3, "click", "disabled"], ["type", "text", "placeholder", "Ex: Introduction aux composants", 1, "mc-input", 3, "ngModelChange", "ngModel"], ["placeholder", "Description du sujet...", "rows", "3", 1, "mc-input", "mc-textarea", 3, "ngModelChange", "ngModel"], [1, "type-pills"], [1, "type-pill", 3, "active"], ["type", "text", "placeholder", "Ex: Documentation Angular", 1, "mc-input", 3, "ngModelChange", "ngModel"], ["placeholder", "R\xE9digez le contenu...", "rows", "6", 1, "mc-input", "mc-textarea", 3, "ngModel"], ["type", "url", "placeholder", "https://...", 1, "mc-input", 3, "ngModel"], [1, "type-pill", 3, "click"], ["placeholder", "R\xE9digez le contenu...", "rows", "6", 1, "mc-input", "mc-textarea", 3, "ngModelChange", "ngModel"], ["type", "url", "placeholder", "https://...", 1, "mc-input", 3, "ngModelChange", "ngModel"], [1, "mode-subtitle"], [1, "resources-picker"], [1, "picker-item", 3, "linked"], [1, "picker-item", 3, "click"], [1, "picker-info"], [1, "picker-title"], [1, "picker-type"], ["nz-icon", "", "nzType", "check-circle", "nzTheme", "outline", 1, "linked-icon"]], template: function CourseEditorPage_Template(rf, ctx) {
|
|
if (rf & 1) {
|
|
\u0275\u0275elementStart(0, "div", 0);
|
|
\u0275\u0275conditionalCreate(1, CourseEditorPage_Conditional_1_Template, 2, 0, "div", 1)(2, CourseEditorPage_Conditional_2_Template, 4, 4);
|
|
\u0275\u0275elementEnd();
|
|
}
|
|
if (rf & 2) {
|
|
\u0275\u0275advance();
|
|
\u0275\u0275conditional(ctx.loading() ? 1 : 2);
|
|
}
|
|
}, dependencies: [FormsModule, DefaultValueAccessor, NgControlStatus, NgModel, NzIconModule, NzIconDirective], styles: ["\n\n.editor-page[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding-bottom: 100px;\n}\n.loading-screen[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n color: #1abc9c;\n}\n.loading-spin[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n@keyframes _ngcontent-%COMP%_spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n.editor-header[_ngcontent-%COMP%] {\n padding: 16px 20px 0;\n border-bottom: 1px solid var(--border);\n padding-bottom: 16px;\n margin-bottom: 0;\n}\n.header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0;\n}\n.back-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n color: var(--text);\n}\n.page-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--text);\n margin: 0;\n}\n.mode-subtitle[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--text-muted);\n margin: 8px 0 0;\n}\n.editor-content[_ngcontent-%COMP%] {\n padding: 16px 20px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.section-card[_ngcontent-%COMP%] {\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 16px;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.section-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 700;\n color: var(--text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin: 0;\n}\n.add-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 10px;\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n cursor: pointer;\n}\n.field-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.field-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n}\n.mc-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 80px;\n line-height: 1.5;\n}\n.topic-item[_ngcontent-%COMP%] {\n border: 1px solid var(--border);\n border-radius: 12px;\n overflow: hidden;\n}\n.topic-item-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background: var(--bg);\n}\n.topic-position[_ngcontent-%COMP%] {\n width: 26px;\n height: 26px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.topic-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.topic-item-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text);\n margin: 0 0 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.topic-item-resources[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-muted);\n}\n.topic-item-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n.icon-action[_ngcontent-%COMP%] {\n width: 30px;\n height: 30px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 14px;\n color: var(--text-muted);\n}\n.icon-action.danger[_ngcontent-%COMP%] {\n color: #ff4d4f;\n}\n.topic-resources[_ngcontent-%COMP%] {\n padding: 8px 12px;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n border-top: 1px solid var(--border);\n}\n.resource-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 20px;\n padding: 4px 10px;\n font-size: 12px;\n color: var(--text);\n}\n.chip-title[_ngcontent-%COMP%] {\n max-width: 120px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.chip-remove[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--text-muted);\n font-size: 11px;\n padding: 0;\n display: flex;\n align-items: center;\n margin-left: 2px;\n}\n.danger-zone[_ngcontent-%COMP%] {\n gap: 10px;\n}\n.publish-btn[_ngcontent-%COMP%] {\n width: 100%;\n background-color: #1abc9c;\n color: #fff;\n border: none;\n border-radius: 12px;\n padding: 14px;\n font-size: 15px;\n font-weight: 700;\n cursor: pointer;\n transition: opacity 0.2s;\n}\n.publish-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n opacity: 0.85;\n}\n.publish-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.status-badge.published[_ngcontent-%COMP%] {\n text-align: center;\n font-size: 13px;\n font-weight: 700;\n color: #1abc9c;\n background: rgba(26, 188, 156, 0.1);\n border: 1px solid rgba(26, 188, 156, 0.3);\n border-radius: 10px;\n padding: 10px;\n}\n.delete-btn[_ngcontent-%COMP%] {\n width: 100%;\n background: none;\n border: 1px solid #ff4d4f;\n color: #ff4d4f;\n border-radius: 12px;\n padding: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: background 0.2s;\n}\n.delete-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 77, 79, 0.08);\n}\n.type-pills[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n.type-pill[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--bg);\n border: 1.5px solid var(--border);\n border-radius: 20px;\n padding: 6px 14px;\n font-size: 13px;\n font-weight: 500;\n color: var(--text-muted);\n cursor: pointer;\n transition: all 0.15s;\n}\n.type-pill.active[_ngcontent-%COMP%] {\n background: var(--primary);\n color: var(--primary-fg);\n border-color: var(--primary);\n}\n.resources-picker[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 20px;\n}\n.picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 12px;\n cursor: pointer;\n transition: border-color 0.15s;\n}\n.picker-item.linked[_ngcontent-%COMP%] {\n border-color: #1abc9c;\n background: rgba(26, 188, 156, 0.05);\n cursor: default;\n}\n.resource-icon-sm[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.picker-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n.picker-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--text);\n margin: 0 0 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.picker-type[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--text-muted);\n}\n.linked-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n color: #1abc9c;\n}\n.empty-hint[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--text-muted);\n margin: 0;\n text-align: center;\n}\n/*# sourceMappingURL=course-editor.css.map */"] });
|
|
};
|
|
(() => {
|
|
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(CourseEditorPage, [{
|
|
type: Component,
|
|
args: [{ selector: "app-course-editor", imports: [FormsModule, NzIconModule], providers: [NzMessageService], template: `<div class="page-container editor-page">
|
|
@if (loading()) {
|
|
<div class="loading-screen">
|
|
<span nz-icon nzType="loading" nzTheme="outline" class="loading-spin"></span>
|
|
</div>
|
|
} @else {
|
|
|
|
<!-- COURSE FORM MODE -->
|
|
@if (mode() === 'course') {
|
|
<div class="editor-header">
|
|
<div class="header-row">
|
|
<button class="back-btn" (click)="goBack()">
|
|
<span nz-icon nzType="arrow-left" nzTheme="outline"></span>
|
|
</button>
|
|
<h1 class="page-title">
|
|
{{ isEditMode() ? 'Modifier le cours' : 'Nouveau cours' }}
|
|
</h1>
|
|
<div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="editor-content">
|
|
<!-- Course info form -->
|
|
<div class="section-card">
|
|
<h2 class="section-label">Informations</h2>
|
|
|
|
<div class="field-group">
|
|
<label class="field-label">Titre du cours</label>
|
|
<input
|
|
type="text"
|
|
class="mc-input"
|
|
placeholder="Ex: Introduction \xE0 Angular"
|
|
[ngModel]="courseTitle()"
|
|
(ngModelChange)="courseTitle.set($event)"
|
|
/>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label class="field-label">Description</label>
|
|
<textarea
|
|
class="mc-input mc-textarea"
|
|
placeholder="D\xE9crivez votre cours..."
|
|
rows="4"
|
|
[ngModel]="courseDescription()"
|
|
(ngModelChange)="courseDescription.set($event)"
|
|
></textarea>
|
|
</div>
|
|
|
|
<button class="mc-btn-primary" (click)="saveCourse()" [disabled]="saving()">
|
|
@if (saving()) { Enregistrement... } @else {
|
|
{{ isEditMode() ? 'Enregistrer les modifications' : 'Cr\xE9er le cours' }}
|
|
}
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Topics (edit mode only) -->
|
|
@if (isEditMode() && course()) {
|
|
<div class="section-card">
|
|
<div class="section-header">
|
|
<h2 class="section-label">Sujets ({{ course()!.topics.length }})</h2>
|
|
<button class="add-btn" (click)="openAddTopic()">
|
|
<span nz-icon nzType="plus" nzTheme="outline"></span>
|
|
Ajouter
|
|
</button>
|
|
</div>
|
|
|
|
@if (course()!.topics.length === 0) {
|
|
<p class="empty-hint">Aucun sujet. Commencez par en ajouter un.</p>
|
|
} @else {
|
|
@for (topic of course()!.topics; track topic.id) {
|
|
<div class="topic-item">
|
|
<div class="topic-item-header">
|
|
<div class="topic-position">{{ topic.position }}</div>
|
|
<div class="topic-item-info">
|
|
<p class="topic-item-title">{{ topic.title }}</p>
|
|
<span class="topic-item-resources">{{ topic.resources.length }} ressource(s)</span>
|
|
</div>
|
|
<div class="topic-item-actions">
|
|
<button class="icon-action" (click)="openLinkResource(topic, $event)" title="Lier une ressource">
|
|
<span nz-icon nzType="link" nzTheme="outline"></span>
|
|
</button>
|
|
<button class="icon-action" (click)="openEditTopic(topic, $event)" title="Modifier">
|
|
<span nz-icon nzType="edit" nzTheme="outline"></span>
|
|
</button>
|
|
<button class="icon-action danger" (click)="deleteTopic(topic, $event)" title="Supprimer">
|
|
<span nz-icon nzType="delete" nzTheme="outline"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Resources of topic -->
|
|
@if (topic.resources.length > 0) {
|
|
<div class="topic-resources">
|
|
@for (resource of topic.resources; track resource.id) {
|
|
<div class="resource-chip">
|
|
<span nz-icon [nzType]="getResourceIcon(resource.type)" nzTheme="outline"></span>
|
|
<span class="chip-title">{{ resource.title }}</span>
|
|
<button class="chip-remove" (click)="unlinkResource(topic, resource, $event)">
|
|
<span nz-icon nzType="close" nzTheme="outline"></span>
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
|
|
<!-- Add resource to catalog -->
|
|
<div class="section-card">
|
|
<div class="section-header">
|
|
<h2 class="section-label">Ressources ({{ allResources().length }})</h2>
|
|
<button class="add-btn" (click)="openAddResource()">
|
|
<span nz-icon nzType="plus" nzTheme="outline"></span>
|
|
Nouvelle
|
|
</button>
|
|
</div>
|
|
@if (allResources().length === 0) {
|
|
<p class="empty-hint">Cr\xE9ez des ressources pour les lier aux sujets.</p>
|
|
} @else {
|
|
@for (resource of allResources(); track resource.id) {
|
|
<div class="topic-item">
|
|
<div class="topic-item-header">
|
|
<div class="resource-icon-sm">
|
|
<span nz-icon [nzType]="getResourceIcon(resource.type)" nzTheme="outline"></span>
|
|
</div>
|
|
<div class="topic-item-info">
|
|
<p class="topic-item-title">{{ resource.title }}</p>
|
|
<span class="topic-item-resources">{{ resource.type }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
|
|
<!-- Publish / Delete -->
|
|
<div class="section-card danger-zone">
|
|
@if (course()!.status === 'Draft') {
|
|
<button class="publish-btn" (click)="publishCourse()" [disabled]="publishing()">
|
|
@if (publishing()) { Publication... } @else { Publier le cours }
|
|
</button>
|
|
} @else {
|
|
<div class="status-badge published">Cours publi\xE9</div>
|
|
}
|
|
<button class="delete-btn" (click)="deleteCourse()">
|
|
<span nz-icon nzType="delete" nzTheme="outline"></span>
|
|
Supprimer le cours
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- TOPIC FORM MODE -->
|
|
@if (mode() === 'topic') {
|
|
<div class="editor-header">
|
|
<div class="header-row">
|
|
<button class="back-btn" (click)="cancelMode()">
|
|
<span nz-icon nzType="arrow-left" nzTheme="outline"></span>
|
|
</button>
|
|
<h1 class="page-title">
|
|
{{ editingTopicId() ? 'Modifier le sujet' : 'Nouveau sujet' }}
|
|
</h1>
|
|
<div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="editor-content">
|
|
<div class="section-card">
|
|
<div class="field-group">
|
|
<label class="field-label">Titre du sujet</label>
|
|
<input
|
|
type="text"
|
|
class="mc-input"
|
|
placeholder="Ex: Introduction aux composants"
|
|
[ngModel]="topicTitle()"
|
|
(ngModelChange)="topicTitle.set($event)"
|
|
/>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label class="field-label">Description (optionnel)</label>
|
|
<textarea
|
|
class="mc-input mc-textarea"
|
|
placeholder="Description du sujet..."
|
|
rows="3"
|
|
[ngModel]="topicDescription()"
|
|
(ngModelChange)="topicDescription.set($event)"
|
|
></textarea>
|
|
</div>
|
|
|
|
<button class="mc-btn-primary" (click)="saveTopic()" [disabled]="saving()">
|
|
@if (saving()) { Enregistrement... } @else {
|
|
{{ editingTopicId() ? 'Mettre \xE0 jour' : 'Ajouter le sujet' }}
|
|
}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- RESOURCE FORM MODE -->
|
|
@if (mode() === 'resource') {
|
|
<div class="editor-header">
|
|
<div class="header-row">
|
|
<button class="back-btn" (click)="cancelMode()">
|
|
<span nz-icon nzType="arrow-left" nzTheme="outline"></span>
|
|
</button>
|
|
<h1 class="page-title">Nouvelle ressource</h1>
|
|
<div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="editor-content">
|
|
<div class="section-card">
|
|
<div class="field-group">
|
|
<label class="field-label">Type</label>
|
|
<div class="type-pills">
|
|
@for (type of resourceTypes; track type) {
|
|
<button
|
|
class="type-pill"
|
|
[class.active]="resourceType() === type"
|
|
(click)="resourceType.set(type)"
|
|
>
|
|
<span nz-icon [nzType]="getResourceIcon(type)" nzTheme="outline"></span>
|
|
{{ type }}
|
|
</button>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label class="field-label">Titre</label>
|
|
<input
|
|
type="text"
|
|
class="mc-input"
|
|
placeholder="Ex: Documentation Angular"
|
|
[ngModel]="resourceTitle()"
|
|
(ngModelChange)="resourceTitle.set($event)"
|
|
/>
|
|
</div>
|
|
|
|
<div class="field-group">
|
|
<label class="field-label">
|
|
@if (resourceType() === 'Text') { Contenu (texte/markdown) }
|
|
@else if (resourceType() === 'File') { Chemin ou URL du fichier }
|
|
@else { URL }
|
|
</label>
|
|
@if (resourceType() === 'Text') {
|
|
<textarea
|
|
class="mc-input mc-textarea"
|
|
placeholder="R\xE9digez le contenu..."
|
|
rows="6"
|
|
[ngModel]="resourceContent()"
|
|
(ngModelChange)="resourceContent.set($event)"
|
|
></textarea>
|
|
} @else {
|
|
<input
|
|
type="url"
|
|
class="mc-input"
|
|
placeholder="https://..."
|
|
[ngModel]="resourceContent()"
|
|
(ngModelChange)="resourceContent.set($event)"
|
|
/>
|
|
}
|
|
</div>
|
|
|
|
<button class="mc-btn-primary" (click)="saveResource()" [disabled]="saving()">
|
|
@if (saving()) { Enregistrement... } @else { Cr\xE9er la ressource }
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
<!-- LINK RESOURCE MODE -->
|
|
@if (mode() === 'link-resource') {
|
|
<div class="editor-header">
|
|
<div class="header-row">
|
|
<button class="back-btn" (click)="cancelMode()">
|
|
<span nz-icon nzType="arrow-left" nzTheme="outline"></span>
|
|
</button>
|
|
<h1 class="page-title">Lier une ressource</h1>
|
|
<div></div>
|
|
</div>
|
|
<p class="mode-subtitle">Sujet : <strong>{{ selectedTopic()?.title }}</strong></p>
|
|
</div>
|
|
|
|
<div class="editor-content">
|
|
@if (allResources().length === 0) {
|
|
<div class="section-card">
|
|
<p class="empty-hint">Aucune ressource disponible. Cr\xE9ez-en une d'abord.</p>
|
|
</div>
|
|
} @else {
|
|
<div class="resources-picker">
|
|
@for (resource of allResources(); track resource.id) {
|
|
<div
|
|
class="picker-item"
|
|
[class.linked]="isResourceLinked(resource)"
|
|
(click)="!isResourceLinked(resource) && linkResource(resource)"
|
|
>
|
|
<div class="resource-icon-sm">
|
|
<span nz-icon [nzType]="getResourceIcon(resource.type)" nzTheme="outline"></span>
|
|
</div>
|
|
<div class="picker-info">
|
|
<p class="picker-title">{{ resource.title }}</p>
|
|
<span class="picker-type">{{ resource.type }}</span>
|
|
</div>
|
|
@if (isResourceLinked(resource)) {
|
|
<span nz-icon nzType="check-circle" nzTheme="outline" class="linked-icon"></span>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
}
|
|
</div>
|
|
`, styles: ["/* src/app/pages/course-editor/course-editor.css */\n.editor-page {\n display: flex;\n flex-direction: column;\n padding-bottom: 100px;\n}\n.loading-screen {\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n color: #1abc9c;\n}\n.loading-spin {\n animation: spin 1s linear infinite;\n}\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n.editor-header {\n padding: 16px 20px 0;\n border-bottom: 1px solid var(--border);\n padding-bottom: 16px;\n margin-bottom: 0;\n}\n.header-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0;\n}\n.back-btn {\n width: 40px;\n height: 40px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n color: var(--text);\n}\n.page-title {\n font-size: 18px;\n font-weight: 700;\n color: var(--text);\n margin: 0;\n}\n.mode-subtitle {\n font-size: 13px;\n color: var(--text-muted);\n margin: 8px 0 0;\n}\n.editor-content {\n padding: 16px 20px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n}\n.section-card {\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 16px;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n.section-label {\n font-size: 13px;\n font-weight: 700;\n color: var(--text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin: 0;\n}\n.add-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 10px;\n padding: 6px 12px;\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n cursor: pointer;\n}\n.field-group {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n.field-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--text);\n}\n.mc-textarea {\n resize: vertical;\n min-height: 80px;\n line-height: 1.5;\n}\n.topic-item {\n border: 1px solid var(--border);\n border-radius: 12px;\n overflow: hidden;\n}\n.topic-item-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px;\n background: var(--bg);\n}\n.topic-position {\n width: 26px;\n height: 26px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 700;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.topic-item-info {\n flex: 1;\n min-width: 0;\n}\n.topic-item-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text);\n margin: 0 0 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.topic-item-resources {\n font-size: 11px;\n color: var(--text-muted);\n}\n.topic-item-actions {\n display: flex;\n gap: 4px;\n}\n.icon-action {\n width: 30px;\n height: 30px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 14px;\n color: var(--text-muted);\n}\n.icon-action.danger {\n color: #ff4d4f;\n}\n.topic-resources {\n padding: 8px 12px;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n border-top: 1px solid var(--border);\n}\n.resource-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 20px;\n padding: 4px 10px;\n font-size: 12px;\n color: var(--text);\n}\n.chip-title {\n max-width: 120px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.chip-remove {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--text-muted);\n font-size: 11px;\n padding: 0;\n display: flex;\n align-items: center;\n margin-left: 2px;\n}\n.danger-zone {\n gap: 10px;\n}\n.publish-btn {\n width: 100%;\n background-color: #1abc9c;\n color: #fff;\n border: none;\n border-radius: 12px;\n padding: 14px;\n font-size: 15px;\n font-weight: 700;\n cursor: pointer;\n transition: opacity 0.2s;\n}\n.publish-btn:hover:not(:disabled) {\n opacity: 0.85;\n}\n.publish-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n.status-badge.published {\n text-align: center;\n font-size: 13px;\n font-weight: 700;\n color: #1abc9c;\n background: rgba(26, 188, 156, 0.1);\n border: 1px solid rgba(26, 188, 156, 0.3);\n border-radius: 10px;\n padding: 10px;\n}\n.delete-btn {\n width: 100%;\n background: none;\n border: 1px solid #ff4d4f;\n color: #ff4d4f;\n border-radius: 12px;\n padding: 12px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: background 0.2s;\n}\n.delete-btn:hover {\n background: rgba(255, 77, 79, 0.08);\n}\n.type-pills {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n.type-pill {\n display: flex;\n align-items: center;\n gap: 5px;\n background: var(--bg);\n border: 1.5px solid var(--border);\n border-radius: 20px;\n padding: 6px 14px;\n font-size: 13px;\n font-weight: 500;\n color: var(--text-muted);\n cursor: pointer;\n transition: all 0.15s;\n}\n.type-pill.active {\n background: var(--primary);\n color: var(--primary-fg);\n border-color: var(--primary);\n}\n.resources-picker {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 20px;\n}\n.picker-item {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 12px;\n padding: 12px;\n cursor: pointer;\n transition: border-color 0.15s;\n}\n.picker-item.linked {\n border-color: #1abc9c;\n background: rgba(26, 188, 156, 0.05);\n cursor: default;\n}\n.resource-icon-sm {\n width: 36px;\n height: 36px;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: var(--text-muted);\n flex-shrink: 0;\n}\n.picker-info {\n flex: 1;\n min-width: 0;\n}\n.picker-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--text);\n margin: 0 0 2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.picker-type {\n font-size: 11px;\n color: var(--text-muted);\n}\n.linked-icon {\n font-size: 18px;\n color: #1abc9c;\n}\n.empty-hint {\n font-size: 13px;\n color: var(--text-muted);\n margin: 0;\n text-align: center;\n}\n/*# sourceMappingURL=course-editor.css.map */\n"] }]
|
|
}], null, null);
|
|
})();
|
|
(() => {
|
|
(typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(CourseEditorPage, { className: "CourseEditorPage", filePath: "src/app/pages/course-editor/course-editor.ts", lineNumber: 23 });
|
|
})();
|
|
|
|
// src/app/pages/course-editor/course-editor.routes.ts
|
|
var COURSE_EDITOR_ROUTES = [
|
|
{ path: "", component: CourseEditorPage }
|
|
];
|
|
export {
|
|
COURSE_EDITOR_ROUTES
|
|
};
|
|
//# sourceMappingURL=chunk-OVXDZVBT.js.map
|