@things-factory/learning 10.1.260 → 10.1.261
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/components/learning-material-form.d.ts +41 -0
- package/dist-client/components/learning-material-form.js +202 -0
- package/dist-client/components/learning-material-form.js.map +1 -0
- package/dist-client/components/learning-unit-form.d.ts +3 -0
- package/dist-client/components/learning-unit-form.js +10 -2
- package/dist-client/components/learning-unit-form.js.map +1 -1
- package/dist-client/pages/learning-course-editor.d.ts +1 -0
- package/dist-client/pages/learning-course-editor.js +19 -6
- package/dist-client/pages/learning-course-editor.js.map +1 -1
- package/dist-client/pages/learning-course-list.d.ts +1 -1
- package/dist-client/pages/learning-course-list.js +6 -2
- package/dist-client/pages/learning-course-list.js.map +1 -1
- package/dist-client/pages/learning-enrollment-status.d.ts +28 -16
- package/dist-client/pages/learning-enrollment-status.js +95 -112
- package/dist-client/pages/learning-enrollment-status.js.map +1 -1
- package/dist-client/pages/learning-view.d.ts +11 -0
- package/dist-client/pages/learning-view.js +94 -19
- package/dist-client/pages/learning-view.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/utils/learning-api.d.ts +48 -3
- package/dist-client/utils/learning-api.js +51 -2
- package/dist-client/utils/learning-api.js.map +1 -1
- package/dist-client/utils/material-source.d.ts +12 -0
- package/dist-client/utils/material-source.js +77 -0
- package/dist-client/utils/material-source.js.map +1 -0
- package/dist-server/ai-reads.js +1 -1
- package/dist-server/ai-reads.js.map +1 -1
- package/dist-server/service/course/course-mutation.d.ts +1 -1
- package/dist-server/service/course/course-mutation.js +7 -6
- package/dist-server/service/course/course-mutation.js.map +1 -1
- package/dist-server/service/course/course-query.d.ts +1 -0
- package/dist-server/service/course/course-query.js +14 -3
- package/dist-server/service/course/course-query.js.map +1 -1
- package/dist-server/service/course/course-rules.d.ts +3 -1
- package/dist-server/service/course/course-rules.js +5 -1
- package/dist-server/service/course/course-rules.js.map +1 -1
- package/dist-server/service/course/course-service.d.ts +5 -4
- package/dist-server/service/course/course-service.js +10 -14
- package/dist-server/service/course/course-service.js.map +1 -1
- package/dist-server/service/course/course-type.d.ts +1 -0
- package/dist-server/service/course/course-type.js +4 -0
- package/dist-server/service/course/course-type.js.map +1 -1
- package/dist-server/service/course/course-unit.d.ts +3 -2
- package/dist-server/service/course/course-unit.js +7 -2
- package/dist-server/service/course/course-unit.js.map +1 -1
- package/dist-server/service/course/index.d.ts +2 -1
- package/dist-server/service/course/index.js +2 -1
- package/dist-server/service/course/index.js.map +1 -1
- package/dist-server/service/course/material-audio.d.ts +1 -0
- package/dist-server/service/course/material-audio.js +43 -0
- package/dist-server/service/course/material-audio.js.map +1 -0
- package/dist-server/service/course/material-draft-mutation.d.ts +13 -0
- package/dist-server/service/course/material-draft-mutation.js +55 -0
- package/dist-server/service/course/material-draft-mutation.js.map +1 -0
- package/dist-server/service/course/material-draft-rules.d.ts +38 -0
- package/dist-server/service/course/material-draft-rules.js +83 -0
- package/dist-server/service/course/material-draft-rules.js.map +1 -0
- package/dist-server/service/course/material-draft-service.d.ts +15 -0
- package/dist-server/service/course/material-draft-service.js +162 -0
- package/dist-server/service/course/material-draft-service.js.map +1 -0
- package/dist-server/service/enrollment/enrollment-query.d.ts +5 -4
- package/dist-server/service/enrollment/enrollment-query.js +26 -35
- package/dist-server/service/enrollment/enrollment-query.js.map +1 -1
- package/dist-server/service/enrollment/enrollment-service.js +13 -3
- package/dist-server/service/enrollment/enrollment-service.js.map +1 -1
- package/dist-server/service/enrollment/enrollment-status.d.ts +31 -18
- package/dist-server/service/enrollment/enrollment-status.js +101 -42
- package/dist-server/service/enrollment/enrollment-status.js.map +1 -1
- package/dist-server/service/enrollment/enrollment-type.d.ts +1 -14
- package/dist-server/service/enrollment/enrollment-type.js +6 -54
- package/dist-server/service/enrollment/enrollment-type.js.map +1 -1
- package/dist-server/service/enrollment/enrollment.d.ts +1 -0
- package/dist-server/service/enrollment/enrollment.js +5 -0
- package/dist-server/service/enrollment/enrollment.js.map +1 -1
- package/dist-server/service/enrollment/learning-ai.d.ts +9 -2
- package/dist-server/service/enrollment/learning-ai.js +25 -28
- package/dist-server/service/enrollment/learning-ai.js.map +1 -1
- package/dist-server/service/enrollment/learning-documents.js +3 -4
- package/dist-server/service/enrollment/learning-documents.js.map +1 -1
- package/dist-server/service/enrollment/progress-rules.d.ts +36 -11
- package/dist-server/service/enrollment/progress-rules.js +47 -12
- package/dist-server/service/enrollment/progress-rules.js.map +1 -1
- package/dist-server/service/enrollment/unit-progress.d.ts +4 -0
- package/dist-server/service/enrollment/unit-progress.js +20 -0
- package/dist-server/service/enrollment/unit-progress.js.map +1 -1
- package/dist-server/service/index.d.ts +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -13
- package/translations/en.json +30 -7
- package/translations/es.json +30 -7
- package/translations/ja.json +30 -7
- package/translations/ko.json +30 -7
- package/translations/ms.json +30 -7
- package/translations/zh.json +30 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment-status.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment-status.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Where enrolments stand, for managers and department heads (ADR-0194 decisions 10, 11): every enrolment of a course or\n * a source with its progress and evidence for a manager (`course` query); for a department head, whether each person\n * of their departments is done - status and days only, never a score or an attempt.\n */\nimport { EntityManager, In } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Department, departmentTreeOf, Employee, withDescendants } from '@things-factory/organization'\nimport { Refusal } from '@things-factory/shell'\n\nimport { Course } from '../course/course'\nimport { CourseUnit } from '../course/course-unit'\nimport { CourseVersion } from '../course/course-version'\nimport { holds, learningManagerOf, publishedVersionOf } from '../course/course-service'\nimport { Enrollment, EnrollmentStatus, OPEN_ENROLLMENT_STATUSES } from './enrollment'\nimport { todayIn } from './enrollment-service'\nimport { counts, overdue } from './progress-rules'\nimport { UnitProgress } from './unit-progress'\n\nexport interface StatusFilter {\n courseId?: string | null\n sourceKind?: string | null\n sourceId?: string | null\n /** ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED or OVERDUE. */\n state?: string | null\n}\n\nexport interface StatusRow {\n enrollment: Enrollment\n user: User | null\n course: Course | null\n departmentName: string | null\n /** The status as it reads today - OVERDUE for an open one past its due day. */\n state: string\n units: number\n unitsDone: number\n versionNumber: number | null\n}\n\n/** The working employee record of each user given - for the department a row names. */\nasync function employeesOf(tx: EntityManager, domain: { id: string }, userIds: string[]): Promise<Map<string, Employee>> {\n if (!userIds.length) return new Map()\n const rows = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, user: { id: In(userIds) } } as any, relations: ['department'] })\n const out = new Map<string, Employee>()\n for (const row of rows) if (row.active !== false && (!out.has(row.userId!) || out.get(row.userId!)!.active === false)) out.set(row.userId!, row)\n return out\n}\n\n/** The rows of the enrolments given - each with its person, course, department, state today and units done. */\nexport async function rowsOf(tx: EntityManager, domain: any, enrollments: Enrollment[]): Promise<StatusRow[]> {\n if (!enrollments.length) return []\n const today = todayIn(domain)\n const users = await tx.getRepository(User).find({ where: { id: In([...new Set(enrollments.map(one => one.userId!))]) } })\n const courses = await tx.getRepository(Course).find({ where: { id: In([...new Set(enrollments.map(one => one.courseId!))]) } as any })\n const employees = await employeesOf(tx, domain, users.map(one => one.id))\n const versionIds = new Set<string>()\n const shown = new Map<string, string | null>()\n for (const enrollment of enrollments) {\n const id = enrollment.versionId ?? (await publishedVersionOf(tx, domain, enrollment.courseId!))?.id ?? null\n shown.set(enrollment.id, id)\n if (id) versionIds.add(id)\n }\n const versions = versionIds.size ? await tx.getRepository(CourseVersion).find({ where: { id: In([...versionIds]) } as any, withDeleted: true }) : []\n const units = versionIds.size ? (await tx.getRepository(CourseUnit).find({ where: { version: { id: In([...versionIds]) } } as any })).filter(counts) : []\n const progress = await tx.getRepository(UnitProgress).find({ where: { enrollment: { id: In(enrollments.map(one => one.id)) } } as any })\n return enrollments.map(enrollment => {\n const versionId = shown.get(enrollment.id)\n const mine = units.filter(unit => unit.versionId === versionId)\n return {\n enrollment,\n user: users.find(one => one.id === enrollment.userId) ?? null,\n course: courses.find(one => one.id === enrollment.courseId) ?? null,\n departmentName: employees.get(enrollment.userId!)?.department?.name ?? null,\n state: overdue(enrollment, today) ? 'OVERDUE' : enrollment.status,\n units: mine.length,\n unitsDone: mine.filter(unit => progress.some(one => one.enrollmentId === enrollment.id && one.unitId === unit.id && one.doneAt)).length,\n versionNumber: enrollment.versionId ? (versions.find(one => one.id === enrollment.versionId)?.number ?? null) : null\n }\n })\n}\n\nconst filtered = (rows: StatusRow[], state?: string | null) => (state ? rows.filter(one => one.state === state) : rows)\n\n/** Every enrolment a manager asks for - by course, by source - with its progress and evidence, the soonest due first. */\nexport async function enrollmentStatus(filter: StatusFilter, context: any): Promise<StatusRow[]> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const where: any = { domain: { id: domain.id } }\n if (filter.courseId) where.course = { id: filter.courseId }\n if (filter.sourceKind) where.sourceKind = filter.sourceKind\n if (filter.sourceId != null && filter.sourceKind) where.sourceId = filter.sourceId\n const enrollments = await tx.getRepository(Enrollment).find({ where, order: { dueOn: 'ASC', createdAt: 'ASC' } as any })\n return filtered(await rowsOf(tx, domain, enrollments), filter.state)\n}\n\n/** The departments the request's person heads, with those under them - none for anyone else. */\nexport async function headedDepartmentsOf(context: any): Promise<string[]> {\n const { domain, user } = context.state\n const tx = learningManagerOf(context)\n const me = (await employeesOf(tx, domain, [user.id])).get(user.id)\n if (!me) return []\n const managed = await tx.getRepository(Department).find({ where: { domain: { id: domain.id }, manager: { id: me.id } } as any })\n if (!managed.length) return []\n return withDescendants(managed.map(one => one.id), await departmentTreeOf(domain, tx))\n}\n\n/**\n * Where the people of the request's departments stand (decision 11) - for a department head: each open or completed\n * enrolment with its state, due day and completion day. Score, attempts and minutes are left out; refused to anyone who\n * heads no department.\n */\nexport async function teamEnrollmentStatus(filter: StatusFilter, context: any): Promise<StatusRow[]> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const headed = await headedDepartmentsOf(context)\n if (!headed.length) throw new Refusal('learning-not-a-department-head', {}, 'only a department head reads where their people stand')\n const people = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, department: { id: In(headed) } } as any })\n const userIds = [...new Set(people.filter(one => one.active !== false && one.userId).map(one => one.userId!))]\n if (!userIds.length) return []\n const where: any = { domain: { id: domain.id }, user: { id: In(userIds) }, status: In([...OPEN_ENROLLMENT_STATUSES, EnrollmentStatus.COMPLETED]) }\n if (filter.courseId) where.course = { id: filter.courseId }\n const enrollments = await tx.getRepository(Enrollment).find({ where, order: { dueOn: 'ASC' } as any })\n return filtered(await rowsOf(tx, domain, enrollments), filter.state).map(row => ({ ...row, enrollment: statusOnly(row.enrollment) }))\n}\n\n/** An enrolment as a department head reads it - where it stands and its days, nothing of how it went. */\nexport function statusOnly(enrollment: Enrollment): Enrollment {\n const { score, attempts, learnedSeconds, acknowledgedAt, certificateNo, cancelReason, ...kept } = enrollment as any\n return { ...kept, score: null, attempts: null, learnedSeconds: null, acknowledgedAt: null, certificateNo: null, cancelReason: null } as Enrollment\n}\n\n/** The completion register of a course - every completed enrolment, by completion day (decision 10). */\nexport async function completionRegister(courseId: string, context: any): Promise<StatusRow[]> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const enrollments = await tx.getRepository(Enrollment).find({ where: { domain: { id: domain.id }, course: { id: courseId }, status: EnrollmentStatus.COMPLETED } as any, order: { completedAt: 'ASC' } as any })\n return await rowsOf(tx, domain, enrollments)\n}\n\n/** Whether the request reads every enrolment - a manager. */\nexport const readsAll = (context: any) => holds(context, 'course', 'query')\n"]}
|
|
1
|
+
{"version":3,"file":"enrollment-status.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment-status.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Where enrolments stand, for managers and department heads (ADR-0194 decisions 10, 11): every enrolment of a course or\n * a source with its progress and evidence for a manager (`course` query); for a department head, whether each person\n * of their departments is done - status and days only, never a score or an attempt.\n */\nimport { EntityManager, In, SelectQueryBuilder } from 'typeorm'\n\nimport { requestHolds, User } from '@things-factory/auth-base'\nimport { Department, departmentTreeOf, Employee, withDescendants } from '@things-factory/organization'\nimport { countListByField, Filter, getQueryBuilderFromListParams, ListParam, ListValueCount, Refusal } from '@things-factory/shell'\n\nimport { Course } from '../course/course'\nimport { CourseUnit } from '../course/course-unit'\nimport { CourseVersion } from '../course/course-version'\nimport { learningManagerOf, publishedVersionOf } from '../course/course-service'\nimport { Enrollment, EnrollmentStatus, OPEN_ENROLLMENT_STATUSES } from './enrollment'\nimport { todayIn } from './enrollment-service'\nimport { counts, overdue } from './progress-rules'\nimport { UnitProgress } from './unit-progress'\n\nexport interface StatusRow {\n enrollment: Enrollment\n user: User | null\n course: Course | null\n departmentName: string | null\n /** The status as it reads today - OVERDUE for an open one past its due day. */\n state: string\n units: number\n unitsDone: number\n versionNumber: number | null\n}\n\n/** The working employee record of each user given - for the department a row names. */\nasync function employeesOf(tx: EntityManager, domain: { id: string }, userIds: string[]): Promise<Map<string, Employee>> {\n if (!userIds.length) return new Map()\n const rows = await tx.getRepository(Employee).find({ where: { domain: { id: domain.id }, user: { id: In(userIds) } } as any, relations: ['department'] })\n const out = new Map<string, Employee>()\n for (const row of rows) if (row.active !== false && (!out.has(row.userId!) || out.get(row.userId!)!.active === false)) out.set(row.userId!, row)\n return out\n}\n\n/** The rows of the enrolments given - each with its person, course, department, state today and units done. */\nexport async function rowsOf(tx: EntityManager, domain: any, enrollments: Enrollment[]): Promise<StatusRow[]> {\n if (!enrollments.length) return []\n const today = todayIn(domain)\n const users = await tx.getRepository(User).find({ where: { id: In([...new Set(enrollments.map(one => one.userId!))]) } })\n const courses = await tx.getRepository(Course).find({ where: { id: In([...new Set(enrollments.map(one => one.courseId!))]) } as any })\n const employees = await employeesOf(tx, domain, users.map(one => one.id))\n const versionIds = new Set<string>()\n const shown = new Map<string, string | null>()\n for (const enrollment of enrollments) {\n const id = enrollment.versionId ?? (await publishedVersionOf(tx, domain, enrollment.courseId!))?.id ?? null\n shown.set(enrollment.id, id)\n if (id) versionIds.add(id)\n }\n const versions = versionIds.size ? await tx.getRepository(CourseVersion).find({ where: { id: In([...versionIds]) } as any, withDeleted: true }) : []\n const units = versionIds.size ? (await tx.getRepository(CourseUnit).find({ where: { version: { id: In([...versionIds]) } } as any })).filter(counts) : []\n const progress = await tx.getRepository(UnitProgress).find({ where: { enrollment: { id: In(enrollments.map(one => one.id)) } } as any })\n return enrollments.map(enrollment => {\n const versionId = shown.get(enrollment.id)\n const mine = units.filter(unit => unit.versionId === versionId)\n return {\n enrollment,\n user: users.find(one => one.id === enrollment.userId) ?? null,\n course: courses.find(one => one.id === enrollment.courseId) ?? null,\n departmentName: employees.get(enrollment.userId!)?.department?.name ?? null,\n state: overdue(enrollment, today) ? 'OVERDUE' : enrollment.status,\n units: mine.length,\n unitsDone: mine.filter(unit => progress.some(one => one.enrollmentId === enrollment.id && one.unitId === unit.id && one.doneAt)).length,\n versionNumber: enrollment.versionId ? (versions.find(one => one.id === enrollment.versionId)?.number ?? null) : null\n }\n })\n}\n\n/** The departments the request's person heads, with those under them - none for anyone else. */\nexport async function headedDepartmentsOf(context: any): Promise<string[]> {\n const { domain, user } = context.state\n const tx = learningManagerOf(context)\n const me = (await employeesOf(tx, domain, [user.id])).get(user.id)\n if (!me) return []\n const managed = await tx.getRepository(Department).find({ where: { domain: { id: domain.id }, manager: { id: me.id } } as any })\n if (!managed.length) return []\n return withDescendants(managed.map(one => one.id), await departmentTreeOf(domain, tx))\n}\n\n/** An enrolment as a department head reads it - where it stands and its days, nothing of how it went. */\nexport function statusOnly(enrollment: Enrollment): Enrollment {\n const { score, attempts, learnedSeconds, acknowledgedAt, certificateNo, cancelReason, ...kept } = enrollment as any\n return { ...kept, score: null, attempts: null, learnedSeconds: null, acknowledgedAt: null, certificateNo: null, cancelReason: null } as Enrollment\n}\n\n/** The completion register of a course - every completed enrolment, by completion day (decision 10). */\nexport async function completionRegister(courseId: string, context: any): Promise<StatusRow[]> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const enrollments = await tx.getRepository(Enrollment).find({ where: { domain: { id: domain.id }, course: { id: courseId }, status: EnrollmentStatus.COMPLETED } as any, order: { completedAt: 'ASC' } as any })\n return await rowsOf(tx, domain, enrollments)\n}\n\n\n/* ================================================================ the list rule */\n\n/** Where an enrolment stands as a list shows it - OVERDUE is an open one past its due day, read on the day. */\nexport const ENROLLMENT_STATES = ['ASSIGNED', 'IN_PROGRESS', 'COMPLETED', 'OVERDUE', 'CANCELLED'] as const\n\n/**\n * Whose enrolments a request reads (decision 11): a manager everyone's; a department head the people of their\n * departments - open and completed ones, status only; anyone else their own.\n */\nexport type EnrollmentReach = { kind: 'all' } | { kind: 'team'; userIds: string[] } | { kind: 'own'; userId: string }\n\n/** The people of the request's departments, refused to anyone who heads none. */\nexport async function teamReachOf(context: any): Promise<EnrollmentReach> {\n const { domain } = context.state\n const headed = await headedDepartmentsOf(context)\n if (!headed.length) throw new Refusal('learning-not-a-department-head', {}, 'only a department head reads where their people stand')\n const people = await learningManagerOf(context).getRepository(Employee).find({ where: { domain: { id: domain.id }, department: { id: In(headed) } } as any })\n return { kind: 'team', userIds: [...new Set(people.filter(one => one.active !== false && one.userId).map(one => one.userId!))] }\n}\n\n/** The widest reach the request has - a manager's, a department head's, or their own. */\nexport async function reachOf(context: any): Promise<EnrollmentReach> {\n if (await requestHolds(context, 'course', 'query')) return { kind: 'all' }\n if ((await headedDepartmentsOf(context)).length) return await teamReachOf(context)\n return { kind: 'own', userId: context.state.user.id }\n}\n\n/*\n * The list's names (getQueryBuilderFromListParams): `course` a course id, `learner` and `courseName` the words a search\n * reads, `sourceKind` and `sourceId` who asked. `state` is not a column - narrowed below.\n */\nconst LIST = {\n alias: 'E',\n searchables: ['learner', 'courseName'],\n columnExpressions: { course: 'C.id', learner: 'U.name', courseName: 'C.name' },\n sortables: ['dueOn', 'createdAt', 'startedAt', 'completedAt', 'learner', 'courseName'],\n defaultSortings: [{ name: 'dueOn' }, { name: 'createdAt' }]\n}\n\nconst valuesOf = (filter: Filter) => (Array.isArray(filter.value) ? filter.value : [filter.value]).map(String).filter(Boolean)\n\n/** The SQL of the states named - the parameters keyed apart so two conditions in one query never meet. */\nfunction stateClause(states: string[], today: string, key: string): { sql: string; parameters: Record<string, any> } | null {\n const parameters: Record<string, any> = { [`${key}Open`]: OPEN_ENROLLMENT_STATUSES, [`${key}Today`]: today }\n const parts = states\n .filter(state => (ENROLLMENT_STATES as readonly string[]).includes(state))\n .map((state, i) => {\n if (state === 'OVERDUE') return `(E.status IN (:...${key}Open) AND E.dueOn IS NOT NULL AND E.dueOn < :${key}Today)`\n parameters[`${key}S${i}`] = state\n if ((OPEN_ENROLLMENT_STATUSES as string[]).includes(state)) return `(E.status = :${key}S${i} AND (E.dueOn IS NULL OR E.dueOn >= :${key}Today))`\n return `E.status = :${key}S${i}`\n })\n return parts.length ? { sql: `(${parts.join(' OR ')})`, parameters } : null\n}\n\nlet narrowSeq = 0\n\n/** The joins the list's names read, the reach, and the `state` filter as SQL. */\nfunction narrow(builder: SelectQueryBuilder<Enrollment>, reach: EnrollmentReach, state: Filter | undefined, today: string, extra?: (builder: SelectQueryBuilder<Enrollment>) => void): void {\n const key = `learningList${narrowSeq++}`\n builder.leftJoin('E.user', 'U').leftJoin('E.course', 'C')\n if (reach.kind === 'own') builder.andWhere(`U.id = :${key}Me`, { [`${key}Me`]: reach.userId })\n if (reach.kind === 'team') {\n if (!reach.userIds.length) builder.andWhere('1 = 0')\n else builder.andWhere(`U.id IN (:...${key}Team)`, { [`${key}Team`]: reach.userIds }).andWhere(`E.status IN (:...${key}Shown)`, { [`${key}Shown`]: [...OPEN_ENROLLMENT_STATUSES, EnrollmentStatus.COMPLETED] })\n }\n const clause = state ? stateClause(valuesOf(state), today, `${key}State`) : null\n if (clause) builder.andWhere(['noteq', 'notin'].includes(state!.operator) ? `NOT ${clause.sql}` : clause.sql, clause.parameters)\n extra?.(builder)\n}\n\n/** The filters but `state`, and the `state` one. */\nfunction splitState(params: ListParam | undefined): { rest: Filter[]; state?: Filter } {\n const filters = params?.filters ?? []\n return { rest: filters.filter(one => one.name !== 'state'), state: filters.find(one => one.name === 'state') }\n}\n\n/**\n * One page of the enrolments a list asks for, within a reach - its conditions, search, sort and page by the framework's\n * list rule, the rows then read with their people, courses and units. A department head's rows are status only.\n */\nexport async function enrollmentPage(params: ListParam, reach: EnrollmentReach, context: any, extra?: (builder: SelectQueryBuilder<Enrollment>) => void): Promise<{ rows: StatusRow[]; total: number }> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const { rest, state } = splitState(params)\n const builder = getQueryBuilderFromListParams({ ...LIST, repository: tx.getRepository(Enrollment), params: { ...params, filters: rest }, domain })\n narrow(builder, reach, state, todayIn(domain), extra)\n const [enrollments, total] = await builder.getManyAndCount()\n const rows = await rowsOf(tx, domain, enrollments)\n return { rows: reach.kind === 'team' ? rows.map(row => ({ ...row, enrollment: statusOnly(row.enrollment) })) : rows, total }\n}\n\n/** How many enrolments stand in each state under the list's other conditions - every state, in order. */\nexport async function enrollmentStateCounts(params: ListParam, reach: EnrollmentReach, context: any): Promise<ListValueCount[]> {\n const { domain } = context.state\n const tx = learningManagerOf(context)\n const today = todayIn(domain)\n const { rest } = splitState(params)\n const common = { ...LIST, repository: tx.getRepository(Enrollment), domain, params: { filters: rest, search: params?.search, inherited: params?.inherited }, field: 'status' }\n const all = await countListByField({ ...common, narrow: builder => narrow(builder, reach, undefined, today) })\n const late = await countListByField({ ...common, narrow: builder => narrow(builder, reach, { name: 'state', operator: 'eq', value: 'OVERDUE' } as Filter, today) })\n const overdueCount = [...late.values()].reduce((sum, one) => sum + one, 0)\n return ENROLLMENT_STATES.map(value => ({ value, count: value === 'OVERDUE' ? overdueCount : (all.get(value) ?? 0) - (late.get(value) ?? 0) }))\n}\n"]}
|
|
@@ -32,12 +32,6 @@ export declare class LearningTickResult {
|
|
|
32
32
|
enrollment: Enrollment;
|
|
33
33
|
progress: UnitProgress;
|
|
34
34
|
}
|
|
35
|
-
export declare class EnrollmentStatusFilter {
|
|
36
|
-
courseId?: string;
|
|
37
|
-
sourceKind?: string;
|
|
38
|
-
sourceId?: string;
|
|
39
|
-
state?: string;
|
|
40
|
-
}
|
|
41
35
|
export declare class EnrollmentStatusRow {
|
|
42
36
|
id: string;
|
|
43
37
|
enrollment: Enrollment;
|
|
@@ -49,16 +43,9 @@ export declare class EnrollmentStatusRow {
|
|
|
49
43
|
unitsDone: number;
|
|
50
44
|
versionNumber?: number | null;
|
|
51
45
|
}
|
|
52
|
-
export declare class EnrollmentStatusSummary {
|
|
53
|
-
total: number;
|
|
54
|
-
assigned: number;
|
|
55
|
-
inProgress: number;
|
|
56
|
-
completed: number;
|
|
57
|
-
overdue: number;
|
|
58
|
-
}
|
|
59
46
|
export declare class EnrollmentStatusList {
|
|
60
47
|
items: EnrollmentStatusRow[];
|
|
61
|
-
|
|
48
|
+
total: number;
|
|
62
49
|
}
|
|
63
50
|
export declare class LearningAudienceInput {
|
|
64
51
|
scope: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LearningContent = exports.LearningContentUnit = exports.LearningEnrollmentList = exports.LearningEnrollmentRow = exports.LearningAudienceInput = exports.EnrollmentStatusList = exports.
|
|
3
|
+
exports.LearningContent = exports.LearningContentUnit = exports.LearningEnrollmentList = exports.LearningEnrollmentRow = exports.LearningAudienceInput = exports.EnrollmentStatusList = exports.EnrollmentStatusRow = exports.LearningTickResult = exports.QuizResultView = exports.QuizAttemptView = exports.QuizQuestionView = exports.QuizChoiceView = exports.LearningUnit = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const type_graphql_1 = require("type-graphql");
|
|
6
6
|
const auth_base_1 = require("@things-factory/auth-base");
|
|
@@ -112,28 +112,6 @@ tslib_1.__decorate([
|
|
|
112
112
|
exports.LearningTickResult = LearningTickResult = tslib_1.__decorate([
|
|
113
113
|
(0, type_graphql_1.ObjectType)({ description: "A tick's result - the unit's progress and the enrolment after it" })
|
|
114
114
|
], LearningTickResult);
|
|
115
|
-
let EnrollmentStatusFilter = class EnrollmentStatusFilter {
|
|
116
|
-
};
|
|
117
|
-
exports.EnrollmentStatusFilter = EnrollmentStatusFilter;
|
|
118
|
-
tslib_1.__decorate([
|
|
119
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'A course.' }),
|
|
120
|
-
tslib_1.__metadata("design:type", String)
|
|
121
|
-
], EnrollmentStatusFilter.prototype, "courseId", void 0);
|
|
122
|
-
tslib_1.__decorate([
|
|
123
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'Who asked - compliance.training-session, learning.direct ...' }),
|
|
124
|
-
tslib_1.__metadata("design:type", String)
|
|
125
|
-
], EnrollmentStatusFilter.prototype, "sourceKind", void 0);
|
|
126
|
-
tslib_1.__decorate([
|
|
127
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'The record that asked - with sourceKind.' }),
|
|
128
|
-
tslib_1.__metadata("design:type", String)
|
|
129
|
-
], EnrollmentStatusFilter.prototype, "sourceId", void 0);
|
|
130
|
-
tslib_1.__decorate([
|
|
131
|
-
(0, type_graphql_1.Field)({ nullable: true, description: 'ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED or OVERDUE.' }),
|
|
132
|
-
tslib_1.__metadata("design:type", String)
|
|
133
|
-
], EnrollmentStatusFilter.prototype, "state", void 0);
|
|
134
|
-
exports.EnrollmentStatusFilter = EnrollmentStatusFilter = tslib_1.__decorate([
|
|
135
|
-
(0, type_graphql_1.InputType)({ description: 'Which enrolments to read' })
|
|
136
|
-
], EnrollmentStatusFilter);
|
|
137
115
|
let EnrollmentStatusRow = class EnrollmentStatusRow {
|
|
138
116
|
};
|
|
139
117
|
exports.EnrollmentStatusRow = EnrollmentStatusRow;
|
|
@@ -176,45 +154,19 @@ tslib_1.__decorate([
|
|
|
176
154
|
exports.EnrollmentStatusRow = EnrollmentStatusRow = tslib_1.__decorate([
|
|
177
155
|
(0, type_graphql_1.ObjectType)({ description: 'One enrolment as the status reads it' })
|
|
178
156
|
], EnrollmentStatusRow);
|
|
179
|
-
let EnrollmentStatusSummary = class EnrollmentStatusSummary {
|
|
180
|
-
};
|
|
181
|
-
exports.EnrollmentStatusSummary = EnrollmentStatusSummary;
|
|
182
|
-
tslib_1.__decorate([
|
|
183
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'All of them, cancelled ones aside.' }),
|
|
184
|
-
tslib_1.__metadata("design:type", Number)
|
|
185
|
-
], EnrollmentStatusSummary.prototype, "total", void 0);
|
|
186
|
-
tslib_1.__decorate([
|
|
187
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Not started.' }),
|
|
188
|
-
tslib_1.__metadata("design:type", Number)
|
|
189
|
-
], EnrollmentStatusSummary.prototype, "assigned", void 0);
|
|
190
|
-
tslib_1.__decorate([
|
|
191
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Started.' }),
|
|
192
|
-
tslib_1.__metadata("design:type", Number)
|
|
193
|
-
], EnrollmentStatusSummary.prototype, "inProgress", void 0);
|
|
194
|
-
tslib_1.__decorate([
|
|
195
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Completed.' }),
|
|
196
|
-
tslib_1.__metadata("design:type", Number)
|
|
197
|
-
], EnrollmentStatusSummary.prototype, "completed", void 0);
|
|
198
|
-
tslib_1.__decorate([
|
|
199
|
-
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Open past their due day.' }),
|
|
200
|
-
tslib_1.__metadata("design:type", Number)
|
|
201
|
-
], EnrollmentStatusSummary.prototype, "overdue", void 0);
|
|
202
|
-
exports.EnrollmentStatusSummary = EnrollmentStatusSummary = tslib_1.__decorate([
|
|
203
|
-
(0, type_graphql_1.ObjectType)({ description: 'How many enrolments stand where' })
|
|
204
|
-
], EnrollmentStatusSummary);
|
|
205
157
|
let EnrollmentStatusList = class EnrollmentStatusList {
|
|
206
158
|
};
|
|
207
159
|
exports.EnrollmentStatusList = EnrollmentStatusList;
|
|
208
160
|
tslib_1.__decorate([
|
|
209
|
-
(0, type_graphql_1.Field)(type => [EnrollmentStatusRow], { description: 'The enrolments.' }),
|
|
161
|
+
(0, type_graphql_1.Field)(type => [EnrollmentStatusRow], { description: 'The enrolments of the page.' }),
|
|
210
162
|
tslib_1.__metadata("design:type", Array)
|
|
211
163
|
], EnrollmentStatusList.prototype, "items", void 0);
|
|
212
164
|
tslib_1.__decorate([
|
|
213
|
-
(0, type_graphql_1.Field)(type =>
|
|
214
|
-
tslib_1.__metadata("design:type",
|
|
215
|
-
], EnrollmentStatusList.prototype, "
|
|
165
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'How many there are under the conditions.' }),
|
|
166
|
+
tslib_1.__metadata("design:type", Number)
|
|
167
|
+
], EnrollmentStatusList.prototype, "total", void 0);
|
|
216
168
|
exports.EnrollmentStatusList = EnrollmentStatusList = tslib_1.__decorate([
|
|
217
|
-
(0, type_graphql_1.ObjectType)({ description: '
|
|
169
|
+
(0, type_graphql_1.ObjectType)({ description: 'A page of enrolments as the status reads them' })
|
|
218
170
|
], EnrollmentStatusList);
|
|
219
171
|
let LearningAudienceInput = class LearningAudienceInput {
|
|
220
172
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment-type.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, InputType, Int, ObjectType } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\n\nimport { Course } from '../course/course'\nimport { CourseUnit } from '../course/course-unit'\nimport { Enrollment } from './enrollment'\nimport { UnitProgress } from './unit-progress'\n\n@ObjectType({ description: 'A unit as its learner sees it - with how far they went through it' })\nexport class LearningUnit {\n @Field(type => CourseUnit, { description: 'The unit.' })\n unit: CourseUnit\n\n @Field(type => UnitProgress, { nullable: true, description: 'How far the learner went - none before they started it.' })\n progress?: UnitProgress | null\n\n @Field({ description: 'Whether it counts toward completion - a link does not.' })\n counts: boolean\n}\n\n@ObjectType({ description: 'A choice as a learner is drawn it - never whether it is right' })\nexport class QuizChoiceView {\n @Field({ description: 'The choice id.' })\n id: string\n\n @Field({ description: 'What it says.' })\n text: string\n}\n\n@ObjectType({ description: 'A question as a learner is drawn it - its choices in the order shown, no answer' })\nexport class QuizQuestionView {\n @Field({ description: 'The question id.' })\n id: string\n\n @Field({ description: 'SINGLE, MULTIPLE or TRUE_FALSE.' })\n kind: string\n\n @Field({ description: 'What it asks.' })\n text: string\n\n @Field(type => [QuizChoiceView], { description: 'Its choices, shuffled.' })\n choices: QuizChoiceView[]\n}\n\n@ObjectType({ description: 'An attempt as a learner is drawn it' })\nexport class QuizAttemptView {\n @Field({ description: 'The attempt id - its answers are sent with it.' })\n attemptId: string\n\n @Field(type => [QuizQuestionView], { description: 'The questions drawn, shuffled.' })\n questions: QuizQuestionView[]\n}\n\n@ObjectType({ description: \"An attempt's result - the score and whether it passed; never the right answers\" })\nexport class QuizResultView {\n @Field(type => Int, { description: 'The score, out of 100.' })\n score: number\n\n @Field({ description: 'Whether it passed.' })\n passed: boolean\n\n @Field(type => Int, { nullable: true, description: 'Attempts left - no limit when empty.' })\n attemptsLeft?: number | null\n\n @Field(type => Enrollment, { description: 'The enrolment after it - completed when nothing else is missing.' })\n enrollment: Enrollment\n}\n\n@ObjectType({ description: \"A tick's result - the unit's progress and the enrolment after it\" })\nexport class LearningTickResult {\n @Field(type => Enrollment, { description: 'The enrolment.' })\n enrollment: Enrollment\n\n @Field(type => UnitProgress, { description: \"The unit's progress.\" })\n progress: UnitProgress\n}\n\n@InputType({ description: 'Which enrolments to read' })\nexport class EnrollmentStatusFilter {\n @Field({ nullable: true, description: 'A course.' })\n courseId?: string\n\n @Field({ nullable: true, description: 'Who asked - compliance.training-session, learning.direct ...' })\n sourceKind?: string\n\n @Field({ nullable: true, description: 'The record that asked - with sourceKind.' })\n sourceId?: string\n\n @Field({ nullable: true, description: 'ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED or OVERDUE.' })\n state?: string\n}\n\n@ObjectType({ description: 'One enrolment as the status reads it' })\nexport class EnrollmentStatusRow {\n @Field({ description: 'The enrolment id.' })\n id: string\n\n @Field(type => Enrollment, { description: 'The enrolment - for a department head its status and days only.' })\n enrollment: Enrollment\n\n @Field(type => User, { nullable: true, description: 'Who takes it.' })\n user?: User | null\n\n @Field(type => Course, { nullable: true, description: 'The course.' })\n course?: Course | null\n\n @Field({ nullable: true, description: 'Their department.' })\n departmentName?: string | null\n\n @Field({ description: 'ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED, or OVERDUE for an open one past its due day.' })\n state: string\n\n @Field(type => Int, { description: 'The units that count.' })\n units: number\n\n @Field(type => Int, { description: 'The units done.' })\n unitsDone: number\n\n @Field(type => Int, { nullable: true, description: 'The version taken.' })\n versionNumber?: number | null\n}\n\n@ObjectType({ description: 'How many enrolments stand where' })\nexport class EnrollmentStatusSummary {\n @Field(type => Int, { description: 'All of them, cancelled ones aside.' })\n total: number\n\n @Field(type => Int, { description: 'Not started.' })\n assigned: number\n\n @Field(type => Int, { description: 'Started.' })\n inProgress: number\n\n @Field(type => Int, { description: 'Completed.' })\n completed: number\n\n @Field(type => Int, { description: 'Open past their due day.' })\n overdue: number\n}\n\n@ObjectType({ description: 'Enrolments and their counts' })\nexport class EnrollmentStatusList {\n @Field(type => [EnrollmentStatusRow], { description: 'The enrolments.' })\n items: EnrollmentStatusRow[]\n\n @Field(type => EnrollmentStatusSummary, { description: 'Their counts.' })\n summary: EnrollmentStatusSummary\n}\n\n@InputType({ description: 'One target of an audience - the domain, a department (with those under it), a role or a person' })\nexport class LearningAudienceInput {\n @Field({ description: 'DOMAIN | DEPARTMENT | ROLE | USER.' })\n scope: string\n\n @Field({ description: 'The id of the domain, department, role or user.' })\n targetId: string\n\n @Field({ nullable: true, description: 'Its name, as shown.' })\n targetName?: string\n}\n\n@ObjectType({ description: 'An enrolment as the assistant lists it' })\nexport class LearningEnrollmentRow {\n @Field({ description: 'The enrolment id.' }) id: string\n @Field({ description: 'Who takes it.' }) learner: string\n @Field({ nullable: true, description: 'Their department.' }) departmentName?: string | null\n @Field({ description: 'The course.' }) course: string\n @Field({ description: 'ASSIGNED, IN_PROGRESS, COMPLETED or OVERDUE.' }) state: string\n @Field({ nullable: true, description: 'YYYY-MM-DD it is due.' }) dueOn?: string | null\n @Field(type => Int, { nullable: true, description: 'Days to the due day - negative past it.' }) daysLeft?: number | null\n @Field({ nullable: true, description: 'When it was started.' }) startedAt?: Date | null\n @Field({ nullable: true, description: 'When it was completed.' }) completedAt?: Date | null\n @Field(type => Int, { description: 'Units done.' }) unitsDone: number\n @Field(type => Int, { description: 'Units that count.' }) units: number\n}\n\n@ObjectType({ description: 'A page of enrolments as the assistant lists them' })\nexport class LearningEnrollmentList {\n @Field(type => [LearningEnrollmentRow], { description: 'The enrolments.' }) items: LearningEnrollmentRow[]\n @Field(type => Int, { description: 'How many there are.' }) total: number\n}\n\n@ObjectType({ description: 'A unit as the assistant reads it' })\nexport class LearningContentUnit {\n @Field(type => Int, { description: 'Its place.' }) seq: number\n @Field({ description: 'VIDEO, PDF, MARKDOWN or LINK.' }) kind: string\n @Field({ description: 'Its name.' }) name: string\n @Field({ nullable: true, description: 'The text of a MARKDOWN unit, the address of a LINK.' }) text?: string | null\n}\n\n@ObjectType({ description: 'The units of one course version, as the assistant reads them' })\nexport class LearningContent {\n @Field({ description: 'The course.' }) course: string\n @Field(type => Int, { description: 'The version number.' }) version: number\n @Field(type => [LearningContentUnit], { description: 'Its units.' }) units: LearningContentUnit[]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"enrollment-type.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment-type.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, InputType, Int, ObjectType } from 'type-graphql'\n\nimport { User } from '@things-factory/auth-base'\n\nimport { Course } from '../course/course'\nimport { CourseUnit } from '../course/course-unit'\nimport { Enrollment } from './enrollment'\nimport { UnitProgress } from './unit-progress'\n\n@ObjectType({ description: 'A unit as its learner sees it - with how far they went through it' })\nexport class LearningUnit {\n @Field(type => CourseUnit, { description: 'The unit.' })\n unit: CourseUnit\n\n @Field(type => UnitProgress, { nullable: true, description: 'How far the learner went - none before they started it.' })\n progress?: UnitProgress | null\n\n @Field({ description: 'Whether it counts toward completion - a link does not.' })\n counts: boolean\n}\n\n@ObjectType({ description: 'A choice as a learner is drawn it - never whether it is right' })\nexport class QuizChoiceView {\n @Field({ description: 'The choice id.' })\n id: string\n\n @Field({ description: 'What it says.' })\n text: string\n}\n\n@ObjectType({ description: 'A question as a learner is drawn it - its choices in the order shown, no answer' })\nexport class QuizQuestionView {\n @Field({ description: 'The question id.' })\n id: string\n\n @Field({ description: 'SINGLE, MULTIPLE or TRUE_FALSE.' })\n kind: string\n\n @Field({ description: 'What it asks.' })\n text: string\n\n @Field(type => [QuizChoiceView], { description: 'Its choices, shuffled.' })\n choices: QuizChoiceView[]\n}\n\n@ObjectType({ description: 'An attempt as a learner is drawn it' })\nexport class QuizAttemptView {\n @Field({ description: 'The attempt id - its answers are sent with it.' })\n attemptId: string\n\n @Field(type => [QuizQuestionView], { description: 'The questions drawn, shuffled.' })\n questions: QuizQuestionView[]\n}\n\n@ObjectType({ description: \"An attempt's result - the score and whether it passed; never the right answers\" })\nexport class QuizResultView {\n @Field(type => Int, { description: 'The score, out of 100.' })\n score: number\n\n @Field({ description: 'Whether it passed.' })\n passed: boolean\n\n @Field(type => Int, { nullable: true, description: 'Attempts left - no limit when empty.' })\n attemptsLeft?: number | null\n\n @Field(type => Enrollment, { description: 'The enrolment after it - completed when nothing else is missing.' })\n enrollment: Enrollment\n}\n\n@ObjectType({ description: \"A tick's result - the unit's progress and the enrolment after it\" })\nexport class LearningTickResult {\n @Field(type => Enrollment, { description: 'The enrolment.' })\n enrollment: Enrollment\n\n @Field(type => UnitProgress, { description: \"The unit's progress.\" })\n progress: UnitProgress\n}\n\n@ObjectType({ description: 'One enrolment as the status reads it' })\nexport class EnrollmentStatusRow {\n @Field({ description: 'The enrolment id.' })\n id: string\n\n @Field(type => Enrollment, { description: 'The enrolment - for a department head its status and days only.' })\n enrollment: Enrollment\n\n @Field(type => User, { nullable: true, description: 'Who takes it.' })\n user?: User | null\n\n @Field(type => Course, { nullable: true, description: 'The course.' })\n course?: Course | null\n\n @Field({ nullable: true, description: 'Their department.' })\n departmentName?: string | null\n\n @Field({ description: 'ASSIGNED, IN_PROGRESS, COMPLETED, CANCELLED, or OVERDUE for an open one past its due day.' })\n state: string\n\n @Field(type => Int, { description: 'The units that count.' })\n units: number\n\n @Field(type => Int, { description: 'The units done.' })\n unitsDone: number\n\n @Field(type => Int, { nullable: true, description: 'The version taken.' })\n versionNumber?: number | null\n}\n\n@ObjectType({ description: 'A page of enrolments as the status reads them' })\nexport class EnrollmentStatusList {\n @Field(type => [EnrollmentStatusRow], { description: 'The enrolments of the page.' })\n items: EnrollmentStatusRow[]\n\n @Field(type => Int, { description: 'How many there are under the conditions.' })\n total: number\n}\n\n@InputType({ description: 'One target of an audience - the domain, a department (with those under it), a role or a person' })\nexport class LearningAudienceInput {\n @Field({ description: 'DOMAIN | DEPARTMENT | ROLE | USER.' })\n scope: string\n\n @Field({ description: 'The id of the domain, department, role or user.' })\n targetId: string\n\n @Field({ nullable: true, description: 'Its name, as shown.' })\n targetName?: string\n}\n\n@ObjectType({ description: 'An enrolment as the assistant lists it' })\nexport class LearningEnrollmentRow {\n @Field({ description: 'The enrolment id.' }) id: string\n @Field({ description: 'Who takes it.' }) learner: string\n @Field({ nullable: true, description: 'Their department.' }) departmentName?: string | null\n @Field({ description: 'The course.' }) course: string\n @Field({ description: 'ASSIGNED, IN_PROGRESS, COMPLETED or OVERDUE.' }) state: string\n @Field({ nullable: true, description: 'YYYY-MM-DD it is due.' }) dueOn?: string | null\n @Field(type => Int, { nullable: true, description: 'Days to the due day - negative past it.' }) daysLeft?: number | null\n @Field({ nullable: true, description: 'When it was started.' }) startedAt?: Date | null\n @Field({ nullable: true, description: 'When it was completed.' }) completedAt?: Date | null\n @Field(type => Int, { description: 'Units done.' }) unitsDone: number\n @Field(type => Int, { description: 'Units that count.' }) units: number\n}\n\n@ObjectType({ description: 'A page of enrolments as the assistant lists them' })\nexport class LearningEnrollmentList {\n @Field(type => [LearningEnrollmentRow], { description: 'The enrolments.' }) items: LearningEnrollmentRow[]\n @Field(type => Int, { description: 'How many there are.' }) total: number\n}\n\n@ObjectType({ description: 'A unit as the assistant reads it' })\nexport class LearningContentUnit {\n @Field(type => Int, { description: 'Its place.' }) seq: number\n @Field({ description: 'VIDEO, PDF, MARKDOWN or LINK.' }) kind: string\n @Field({ description: 'Its name.' }) name: string\n @Field({ nullable: true, description: 'The text of a MARKDOWN unit, the address of a LINK.' }) text?: string | null\n}\n\n@ObjectType({ description: 'The units of one course version, as the assistant reads them' })\nexport class LearningContent {\n @Field({ description: 'The course.' }) course: string\n @Field(type => Int, { description: 'The version number.' }) version: number\n @Field(type => [LearningContentUnit], { description: 'Its units.' }) units: LearningContentUnit[]\n}\n"]}
|
|
@@ -140,6 +140,11 @@ tslib_1.__decorate([
|
|
|
140
140
|
(0, type_graphql_1.Field)({ nullable: true, description: 'The worklist to-do handed out for it.' }),
|
|
141
141
|
tslib_1.__metadata("design:type", String)
|
|
142
142
|
], Enrollment.prototype, "todoInstanceId", void 0);
|
|
143
|
+
tslib_1.__decorate([
|
|
144
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
145
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The unit learned last - the course opens on it again, on any device.' }),
|
|
146
|
+
tslib_1.__metadata("design:type", String)
|
|
147
|
+
], Enrollment.prototype, "lastUnitId", void 0);
|
|
143
148
|
tslib_1.__decorate([
|
|
144
149
|
(0, typeorm_1.CreateDateColumn)(),
|
|
145
150
|
(0, type_graphql_1.Field)({ nullable: true, description: 'Creation timestamp.' }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, Int, ObjectType, registerEnumType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain } from '@things-factory/shell'\n\nimport { Course } from '../course/course'\nimport { CourseVersion } from '../course/course-version'\n\n/** Where an enrolment stands - one past its due day and not completed reads as overdue, it is not kept. */\nexport enum EnrollmentStatus {\n ASSIGNED = 'ASSIGNED',\n IN_PROGRESS = 'IN_PROGRESS',\n COMPLETED = 'COMPLETED',\n CANCELLED = 'CANCELLED'\n}\n\nregisterEnumType(EnrollmentStatus, { name: 'EnrollmentStatus', description: 'ASSIGNED - not started; IN_PROGRESS - started; COMPLETED - every condition met; CANCELLED - withdrawn by who asked for it, or by a manager.' })\n\n/** The statuses of an open enrolment - one per person, course and source. */\nexport const OPEN_ENROLLMENT_STATUSES = [EnrollmentStatus.ASSIGNED, EnrollmentStatus.IN_PROGRESS]\n\n/**\n * 수강 (ADR-0194 decisions 5, 7, 8) - one person to take one course by a day, for whoever asked (`sourceKind` and\n * `sourceId`: `compliance.training-session` and the session, `learning.direct` for a manager's own). The version is fixed when\n * the person starts. Open ones are one per person, course and source (a partial unique index). A completion keeps its\n * evidence - minutes, score, attempts, when it was confirmed, the version - and is never deleted: a wrong one is\n * cancelled with a reason.\n */\n@Entity({ name: 'learning_enrollments' })\n@Index('ix_learning_enrollment_0', (row: Enrollment) => [row.domain, row.user, row.course, row.sourceKind, row.sourceId], {\n unique: true,\n where: `\"deleted_at\" IS NULL AND \"status\" IN ('ASSIGNED', 'IN_PROGRESS')`\n})\n@Index('ix_learning_enrollment_1', (row: Enrollment) => [row.domain, row.course, row.status])\n@Index('ix_learning_enrollment_2', (row: Enrollment) => [row.domain, row.sourceKind, row.sourceId])\n@ObjectType({ description: 'An enrolment - one person to take one course by a day, for whoever asked, with the evidence of its completion.' })\nexport class Enrollment {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Enrollment id.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain.' })\n domain?: Domain\n\n @RelationId((row: Enrollment) => row.domain)\n domainId?: string\n\n @ManyToOne(type => User)\n @Field(type => User, { nullable: true, description: 'Who takes it.' })\n user?: User\n\n @RelationId((row: Enrollment) => row.user)\n userId?: string\n\n @ManyToOne(type => Course)\n @Field(type => Course, { nullable: true, description: 'The course.' })\n course?: Course\n\n @RelationId((row: Enrollment) => row.course)\n courseId?: string\n\n @ManyToOne(type => CourseVersion, { nullable: true })\n @Field(type => CourseVersion, { nullable: true, description: 'The version taken - fixed when the person starts.' })\n version?: CourseVersion\n\n @RelationId((row: Enrollment) => row.version)\n versionId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'YYYY-MM-DD it is to be completed by.' })\n dueOn?: string\n\n @Column()\n @Field({ description: 'The module and kind of record that asked for it - compliance.training-session, learning.direct ...' })\n sourceKind: string\n\n @Column({ default: '' })\n @Field({ description: 'The record that asked for it - empty for a manager\\'s own.' })\n sourceId: string\n\n @Column({ default: EnrollmentStatus.ASSIGNED })\n @Field(type => EnrollmentStatus, { description: 'Where it stands.' })\n status: EnrollmentStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When the person started.' })\n startedAt?: Date\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'The seconds the server counted on its units.' })\n learnedSeconds: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When the person confirmed the acknowledgement.' })\n acknowledgedAt?: Date\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'The best score of the quiz, out of 100.' })\n score?: number\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'How many quiz attempts were sent.' })\n attempts: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When it was completed.' })\n completedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The certificate number - given at completion.' })\n certificateNo?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When it was cancelled.' })\n cancelledAt?: Date\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Why it was cancelled.' })\n cancelReason?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The worklist to-do handed out for it.' })\n todoInstanceId?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Creation timestamp.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Last update timestamp.' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'Soft delete timestamp.' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who made it.' })\n creator?: User\n\n @RelationId((row: Enrollment) => row.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who changed it last.' })\n updater?: User\n\n @RelationId((row: Enrollment) => row.updater)\n updaterId?: string\n}\n"]}
|
|
1
|
+
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../../server/service/enrollment/enrollment.ts"],"names":[],"mappings":"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","sourcesContent":["import { Field, ID, Int, ObjectType, registerEnumType } from 'type-graphql'\nimport { Column, CreateDateColumn, DeleteDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\n\nimport { User } from '@things-factory/auth-base'\nimport { Domain } from '@things-factory/shell'\n\nimport { Course } from '../course/course'\nimport { CourseVersion } from '../course/course-version'\n\n/** Where an enrolment stands - one past its due day and not completed reads as overdue, it is not kept. */\nexport enum EnrollmentStatus {\n ASSIGNED = 'ASSIGNED',\n IN_PROGRESS = 'IN_PROGRESS',\n COMPLETED = 'COMPLETED',\n CANCELLED = 'CANCELLED'\n}\n\nregisterEnumType(EnrollmentStatus, { name: 'EnrollmentStatus', description: 'ASSIGNED - not started; IN_PROGRESS - started; COMPLETED - every condition met; CANCELLED - withdrawn by who asked for it, or by a manager.' })\n\n/** The statuses of an open enrolment - one per person, course and source. */\nexport const OPEN_ENROLLMENT_STATUSES = [EnrollmentStatus.ASSIGNED, EnrollmentStatus.IN_PROGRESS]\n\n/**\n * 수강 (ADR-0194 decisions 5, 7, 8) - one person to take one course by a day, for whoever asked (`sourceKind` and\n * `sourceId`: `compliance.training-session` and the session, `learning.direct` for a manager's own). The version is fixed when\n * the person starts. Open ones are one per person, course and source (a partial unique index). A completion keeps its\n * evidence - minutes, score, attempts, when it was confirmed, the version - and is never deleted: a wrong one is\n * cancelled with a reason.\n */\n@Entity({ name: 'learning_enrollments' })\n@Index('ix_learning_enrollment_0', (row: Enrollment) => [row.domain, row.user, row.course, row.sourceKind, row.sourceId], {\n unique: true,\n where: `\"deleted_at\" IS NULL AND \"status\" IN ('ASSIGNED', 'IN_PROGRESS')`\n})\n@Index('ix_learning_enrollment_1', (row: Enrollment) => [row.domain, row.course, row.status])\n@Index('ix_learning_enrollment_2', (row: Enrollment) => [row.domain, row.sourceKind, row.sourceId])\n@ObjectType({ description: 'An enrolment - one person to take one course by a day, for whoever asked, with the evidence of its completion.' })\nexport class Enrollment {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Enrollment id.' })\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain.' })\n domain?: Domain\n\n @RelationId((row: Enrollment) => row.domain)\n domainId?: string\n\n @ManyToOne(type => User)\n @Field(type => User, { nullable: true, description: 'Who takes it.' })\n user?: User\n\n @RelationId((row: Enrollment) => row.user)\n userId?: string\n\n @ManyToOne(type => Course)\n @Field(type => Course, { nullable: true, description: 'The course.' })\n course?: Course\n\n @RelationId((row: Enrollment) => row.course)\n courseId?: string\n\n @ManyToOne(type => CourseVersion, { nullable: true })\n @Field(type => CourseVersion, { nullable: true, description: 'The version taken - fixed when the person starts.' })\n version?: CourseVersion\n\n @RelationId((row: Enrollment) => row.version)\n versionId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'YYYY-MM-DD it is to be completed by.' })\n dueOn?: string\n\n @Column()\n @Field({ description: 'The module and kind of record that asked for it - compliance.training-session, learning.direct ...' })\n sourceKind: string\n\n @Column({ default: '' })\n @Field({ description: 'The record that asked for it - empty for a manager\\'s own.' })\n sourceId: string\n\n @Column({ default: EnrollmentStatus.ASSIGNED })\n @Field(type => EnrollmentStatus, { description: 'Where it stands.' })\n status: EnrollmentStatus\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When the person started.' })\n startedAt?: Date\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'The seconds the server counted on its units.' })\n learnedSeconds: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When the person confirmed the acknowledgement.' })\n acknowledgedAt?: Date\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'The best score of the quiz, out of 100.' })\n score?: number\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'How many quiz attempts were sent.' })\n attempts: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When it was completed.' })\n completedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The certificate number - given at completion.' })\n certificateNo?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When it was cancelled.' })\n cancelledAt?: Date\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Why it was cancelled.' })\n cancelReason?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The worklist to-do handed out for it.' })\n todoInstanceId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The unit learned last - the course opens on it again, on any device.' })\n lastUnitId?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Creation timestamp.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Last update timestamp.' })\n updatedAt?: Date\n\n @DeleteDateColumn()\n @Field({ nullable: true, description: 'Soft delete timestamp.' })\n deletedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who made it.' })\n creator?: User\n\n @RelationId((row: Enrollment) => row.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Who changed it last.' })\n updater?: User\n\n @RelationId((row: Enrollment) => row.updater)\n updaterId?: string\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ListParam } from '@things-factory/shell';
|
|
1
2
|
export interface ReadableEnrollment {
|
|
2
3
|
id: string;
|
|
3
4
|
learner: string;
|
|
@@ -11,8 +12,14 @@ export interface ReadableEnrollment {
|
|
|
11
12
|
unitsDone: number;
|
|
12
13
|
units: number;
|
|
13
14
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* A page of the enrolments the person may read, as rows the assistant lists - cancelled ones left out. Conditions, search
|
|
17
|
+
* and page by the list rule of the status screen (`enrollmentPage`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function readableEnrollments(params: ListParam, context: any): Promise<{
|
|
20
|
+
items: ReadableEnrollment[];
|
|
21
|
+
total: number;
|
|
22
|
+
}>;
|
|
16
23
|
export interface CourseContent {
|
|
17
24
|
course: string;
|
|
18
25
|
version: number;
|
|
@@ -15,6 +15,7 @@ exports.choicesOfText = choicesOfText;
|
|
|
15
15
|
* until a manager looks it over and saves it; a version with one is not published.
|
|
16
16
|
*/
|
|
17
17
|
const typeorm_1 = require("typeorm");
|
|
18
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
18
19
|
const shell_1 = require("@things-factory/shell");
|
|
19
20
|
const course_1 = require("../course/course");
|
|
20
21
|
const course_version_1 = require("../course/course-version");
|
|
@@ -24,34 +25,30 @@ const enrollment_service_1 = require("./enrollment-service");
|
|
|
24
25
|
const enrollment_status_1 = require("./enrollment-status");
|
|
25
26
|
const quiz_attempt_1 = require("./quiz-attempt");
|
|
26
27
|
const daysBetween = (from, to) => Math.round((Date.parse(`${to}T00:00:00Z`) - Date.parse(`${from}T00:00:00Z`)) / 86_400_000);
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
rows = await (0, enrollment_status_1.teamEnrollmentStatus)({}, context);
|
|
35
|
-
else {
|
|
36
|
-
const mine = await (0, course_service_1.learningManagerOf)(context).getRepository(enrollment_1.Enrollment).find({ where: { domain: { id: domain.id }, user: { id: user.id } } });
|
|
37
|
-
rows = await (0, enrollment_status_1.rowsOf)((0, course_service_1.learningManagerOf)(context), domain, mine);
|
|
38
|
-
}
|
|
28
|
+
/**
|
|
29
|
+
* A page of the enrolments the person may read, as rows the assistant lists - cancelled ones left out. Conditions, search
|
|
30
|
+
* and page by the list rule of the status screen (`enrollmentPage`).
|
|
31
|
+
*/
|
|
32
|
+
async function readableEnrollments(params, context) {
|
|
33
|
+
const { domain } = context.state;
|
|
34
|
+
const { rows, total } = await (0, enrollment_status_1.enrollmentPage)(params, await (0, enrollment_status_1.reachOf)(context), context, builder => builder.andWhere('E.status <> :learningAiCancelled', { learningAiCancelled: enrollment_1.EnrollmentStatus.CANCELLED }));
|
|
39
35
|
const today = (0, enrollment_service_1.todayIn)(domain);
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
.map(row => ({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
36
|
+
return {
|
|
37
|
+
total,
|
|
38
|
+
items: rows.map(row => ({
|
|
39
|
+
id: row.enrollment.id,
|
|
40
|
+
learner: row.user?.name ?? '',
|
|
41
|
+
departmentName: row.departmentName,
|
|
42
|
+
course: row.course?.name ?? '',
|
|
43
|
+
state: row.state,
|
|
44
|
+
dueOn: row.enrollment.dueOn ?? null,
|
|
45
|
+
daysLeft: row.enrollment.dueOn ? daysBetween(today, row.enrollment.dueOn) : null,
|
|
46
|
+
startedAt: row.enrollment.startedAt ?? null,
|
|
47
|
+
completedAt: row.enrollment.completedAt ?? null,
|
|
48
|
+
unitsDone: row.unitsDone,
|
|
49
|
+
units: row.units
|
|
50
|
+
}))
|
|
51
|
+
};
|
|
55
52
|
}
|
|
56
53
|
/**
|
|
57
54
|
* The units of one version as the assistant reads them. With an enrolment - the person's own - its version and nothing
|
|
@@ -69,7 +66,7 @@ async function courseContent(args, context) {
|
|
|
69
66
|
version = await (0, enrollment_service_1.shownVersionOf)(tx, domain, enrollment);
|
|
70
67
|
}
|
|
71
68
|
else if (args.versionId) {
|
|
72
|
-
if (!(await (0,
|
|
69
|
+
if (!(await (0, auth_base_1.requestHolds)(context, 'course', 'query')))
|
|
73
70
|
throw new shell_1.Refusal('learning-not-found', {}, 'the record was not found. reload and try again.');
|
|
74
71
|
version = await tx.getRepository(course_version_1.CourseVersion).findOne({ where: { id: args.versionId, domain: { id: domain.id } }, withDeleted: true });
|
|
75
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learning-ai.js","sourceRoot":"","sources":["../../../server/service/enrollment/learning-ai.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"learning-ai.js","sourceRoot":"","sources":["../../../server/service/enrollment/learning-ai.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * What the assistant reads and enters of learning (ADR-0194 decision 12), as the person asking:\n *\n * - `learning.enrollments` - the enrolments the person may read: a manager every one, a department head their people's\n * (status only), anyone else their own - 「기한이 일주일 남았는데 시작하지 않은 사람」.\n * - `learning.course-content` - the units of one version, to answer a question on a course or to draft its questions:\n * a learner the version of their own enrolment and nothing else, never while a quiz attempt of theirs is open; a manager\n * any version.\n * - `learning.question-draft` - questions drafted from the units, entered into a draft version only, each marked drafted\n * until a manager looks it over and saves it; a version with one is not published.\n */\nimport { EntityManager, IsNull } from 'typeorm'\n\nimport { requestHolds } from '@things-factory/auth-base'\nimport { ListParam, Refusal } from '@things-factory/shell'\n\nimport { Course } from '../course/course'\nimport { CourseUnit } from '../course/course-unit'\nimport { CourseVersion } from '../course/course-version'\nimport { learningManagerOf, unitsOf } from '../course/course-service'\nimport { Enrollment, EnrollmentStatus, OPEN_ENROLLMENT_STATUSES } from './enrollment'\nimport { myEnrollmentOf, shownVersionOf, todayIn } from './enrollment-service'\nimport { enrollmentPage, reachOf } from './enrollment-status'\nimport { QuizAttempt } from './quiz-attempt'\n\nexport interface ReadableEnrollment {\n id: string\n learner: string\n departmentName: string | null\n course: string\n state: string\n dueOn: string | null\n daysLeft: number | null\n startedAt: Date | null\n completedAt: Date | null\n unitsDone: number\n units: number\n}\n\nconst daysBetween = (from: string, to: string) => Math.round((Date.parse(`${to}T00:00:00Z`) - Date.parse(`${from}T00:00:00Z`)) / 86_400_000)\n\n/**\n * A page of the enrolments the person may read, as rows the assistant lists - cancelled ones left out. Conditions, search\n * and page by the list rule of the status screen (`enrollmentPage`).\n */\nexport async function readableEnrollments(params: ListParam, context: any): Promise<{ items: ReadableEnrollment[]; total: number }> {\n const { domain } = context.state\n const { rows, total } = await enrollmentPage(params, await reachOf(context), context, builder => builder.andWhere('E.status <> :learningAiCancelled', { learningAiCancelled: EnrollmentStatus.CANCELLED }))\n const today = todayIn(domain)\n return {\n total,\n items: rows.map(row => ({\n id: row.enrollment.id,\n learner: row.user?.name ?? '',\n departmentName: row.departmentName,\n course: row.course?.name ?? '',\n state: row.state,\n dueOn: row.enrollment.dueOn ?? null,\n daysLeft: row.enrollment.dueOn ? daysBetween(today, row.enrollment.dueOn) : null,\n startedAt: row.enrollment.startedAt ?? null,\n completedAt: row.enrollment.completedAt ?? null,\n unitsDone: row.unitsDone,\n units: row.units\n }))\n }\n}\n\nexport interface CourseContent {\n course: string\n version: number\n units: { seq: number; kind: string; name: string; text: string | null }[]\n}\n\n/**\n * The units of one version as the assistant reads them. With an enrolment - the person's own - its version and nothing\n * else, refused while a quiz attempt of it is open: the assistant does not answer the quiz. With a version - a manager's.\n */\nexport async function courseContent(args: { enrollmentId?: string | null; versionId?: string | null }, context: any): Promise<CourseContent> {\n const { domain } = context.state\n const tx: EntityManager = learningManagerOf(context)\n let version: CourseVersion | null\n if (args.enrollmentId) {\n const enrollment = await myEnrollmentOf(context, args.enrollmentId, tx)\n const open = await tx.getRepository(QuizAttempt).count({ where: { enrollment: { id: enrollment.id }, submittedAt: IsNull() } as any })\n if (open && (OPEN_ENROLLMENT_STATUSES as string[]).includes(enrollment.status))\n throw new Refusal('learning-quiz-in-progress', {}, 'a quiz attempt is open - the course is not explained until it is sent')\n version = await shownVersionOf(tx, domain, enrollment)\n } else if (args.versionId) {\n if (!(await requestHolds(context, 'course', 'query'))) throw new Refusal('learning-not-found', {}, 'the record was not found. reload and try again.')\n version = await tx.getRepository(CourseVersion).findOne({ where: { id: args.versionId, domain: { id: domain.id } } as any, withDeleted: true })\n } else throw new Refusal('learning-content-what', {}, 'name the enrolment or the version')\n if (!version) throw new Refusal('learning-not-found', {}, 'the record was not found. reload and try again.')\n const course = await tx.getRepository(Course).findOneBy({ id: version.courseId! })\n const units: CourseUnit[] = await unitsOf(tx, version.id)\n return {\n course: course?.name ?? '',\n version: version.number,\n units: units.map(unit => ({ seq: unit.seq, kind: unit.kind, name: unit.name, text: unit.kind === 'MARKDOWN' ? unit.body ?? null : unit.kind === 'LINK' ? unit.url ?? null : null }))\n }\n}\n\n/** \"a\\n*b\\nc\" - one choice a line, the right ones starting with `*` - as the editor's choices. */\nexport function choicesOfText(text: string): { text: string; correct: boolean }[] {\n return String(text ?? '')\n .split(/\\r?\\n/)\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => ({ text: line.replace(/^\\*\\s*/, ''), correct: line.startsWith('*') }))\n}\n"]}
|
|
@@ -12,7 +12,6 @@ const pdf_1 = require("@things-factory/pdf");
|
|
|
12
12
|
const shell_1 = require("@things-factory/shell");
|
|
13
13
|
const course_1 = require("../course/course");
|
|
14
14
|
const course_version_1 = require("../course/course-version");
|
|
15
|
-
const course_service_1 = require("../course/course-service");
|
|
16
15
|
const enrollment_1 = require("./enrollment");
|
|
17
16
|
const enrollment_status_1 = require("./enrollment-status");
|
|
18
17
|
exports.LEARNING_CERTIFICATE_KIND = 'learning.certificate';
|
|
@@ -82,7 +81,7 @@ async function mayHaveCertificate(context, id) {
|
|
|
82
81
|
const enrollment = await enrollmentFor(context, id ?? '');
|
|
83
82
|
if (!enrollment || enrollment.status !== enrollment_1.EnrollmentStatus.COMPLETED)
|
|
84
83
|
return false;
|
|
85
|
-
return enrollment.userId === context.state.user?.id || (await (0,
|
|
84
|
+
return enrollment.userId === context.state.user?.id || (await (0, auth_base_1.requestHolds)(context, 'course', 'query'));
|
|
86
85
|
}
|
|
87
86
|
function registerLearningDocuments() {
|
|
88
87
|
(0, pdf_1.registerIssuedDocumentKind)({
|
|
@@ -150,10 +149,10 @@ function registerLearningDocuments() {
|
|
|
150
149
|
};
|
|
151
150
|
},
|
|
152
151
|
async mayIssue(context) {
|
|
153
|
-
return await (0,
|
|
152
|
+
return await (0, auth_base_1.requestHolds)(context, 'course', 'query');
|
|
154
153
|
},
|
|
155
154
|
async mayRead(context) {
|
|
156
|
-
return await (0,
|
|
155
|
+
return await (0, auth_base_1.requestHolds)(context, 'course', 'query');
|
|
157
156
|
}
|
|
158
157
|
});
|
|
159
158
|
}
|