Skip to content

Commit a8efa53

Browse files
committed
[studio] construct custom courseware for DIF
1 parent 6e4a3cb commit a8efa53

File tree

3 files changed

+43
-33
lines changed

3 files changed

+43
-33
lines changed

agent/courseware-refactor-plan.md

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,51 +54,49 @@ Refactor the `courses` package to `courseware` with proper abstraction naming an
5454
---
5555

5656
## Phase 2: DataInputForm Dependency Injection
57-
**Goal**: Replace global `allCourses` dependency with injected courseware prop
57+
**Goal**: Replace global `allCourseWare` dependency with injected courseware prop
5858

5959
### 2.1 Add CourseWare Prop to DataInputForm
60-
- [ ] Add `courseWare` prop to `DataInputForm.vue`
61-
- [ ] Type prop as `AllCourseWare` interface
62-
- [ ] Make prop required with reasonable default
63-
- [ ] Update component documentation
60+
- [x] Add `courseWare` prop to `DataInputForm.vue` with `AllCourseWare` type
61+
- [x] Set default prop value to imported `allCourseWare` for backward compatibility
62+
- [x] Add `PropType` import for proper typing
6463

6564
### 2.2 Replace Global Dependencies
66-
- [ ] Replace `allCourses.getCourse()` calls with `this.courseWare.getCourseWare()`
67-
- [ ] Replace `allCourses.courses` with `this.courseWare.courseWareList`
68-
- [ ] Update `getImplementingViews()` method to use injected courseware
69-
- [ ] Remove direct `allCourses` import from `DataInputForm.vue`
65+
- [x] Replace `allCourseWare.getCourse()` calls with `this.courseWare.getCourseWare()`
66+
- [x] Update `getImplementingViews()` method to use injected courseware
67+
- [x] Keep `allCourseWare` import for default value and type
7068

7169
### 2.3 Update DataInputForm Consumers
72-
- [ ] Update `CreateCardView.vue` to pass courseware prop
73-
- [ ] Update platform-ui usage of `DataInputForm`
74-
- [ ] Update any other `DataInputForm` consumers
70+
- [x] Update `CreateCardView.vue` to pass courseware prop (currently uses default)
71+
- [x] Platform-ui usage preserved (uses default prop automatically)
72+
- [x] Backward compatibility maintained
7573

76-
**Validation**: DataInputForm works with both default and custom courseware
74+
**Validation**: DataInputForm works with both default and custom courseware
7775

7876
---
7977

8078
## Phase 3: Studio-UI Custom CourseWare Integration
8179
**Goal**: Enable studio-ui to construct custom courseware including custom questions
8280

8381
### 3.1 Create Custom CourseWare Builder
84-
- [ ] Create `utils/customCourseWareBuilder.ts` in studio-ui
85-
- [ ] Function to merge default courseware with custom questions
86-
- [ ] Function to create `CourseWare` instances from custom questions
87-
- [ ] Function to build `AllCourseWare` registry with custom content
82+
- [x] Create `utils/customCourseWareBuilder.ts` in studio-ui
83+
- [x] Function to merge default courseware with custom questions
84+
- [x] Function to create `CourseWare` instances from custom questions
85+
- [x] Function to build `AllCourseWare` registry with custom content
8886

8987
### 3.2 Integrate Custom Questions into CourseWare
90-
- [ ] Convert custom questions to `CourseWare` instances
91-
- [ ] Add custom `CourseWare` to `AllCourseWare` registry
92-
- [ ] Ensure custom questions available in courseware lookup
93-
- [ ] Maintain backward compatibility with existing questions
88+
- [x] Convert custom questions to `CourseWare` instances using CourseWare constructor
89+
- [x] Add custom `CourseWare` to `AllCourseWare` registry with conflict handling
90+
- [x] Ensure custom questions available in courseware lookup
91+
- [x] Maintain backward compatibility with existing questions
9492

9593
### 3.3 Update Studio-UI Components
96-
- [ ] Update `main.ts` to build custom courseware registry
97-
- [ ] Pass custom courseware to `CreateCardView`
98-
- [ ] Update `CreateCardView` to use custom courseware in `DataInputForm`
99-
- [ ] Test custom question rendering in studio-ui
94+
- [x] Update `main.ts` to build custom courseware registry using buildStudioCourseWare()
95+
- [x] Pass custom courseware to `CreateCardView` via provide/inject pattern
96+
- [x] Update `CreateCardView` to use custom courseware in `DataInputForm` via courseWare prop
97+
- [x] Update view components collection to use custom registry
10098

101-
**Validation**: Custom questions appear and render correctly in studio-ui CreateCard
99+
**Validation**: Custom questions appear and render correctly in studio-ui CreateCard
102100

103101
---
104102

packages/studio-ui/src/main.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ const vuetify = createVuetify({
6060

6161
// Register all course view components globally (like platform-ui)
6262
console.log('🎨 Studio Mode: Importing course view components');
63-
const { allCourseWare: Courses } = await import('@vue-skuilder/courseware');
6463
console.log(' ✅ Course components imported successfully');
6564

6665
// Check for custom questions configuration and import if available
@@ -137,8 +136,17 @@ const vuetify = createVuetify({
137136
}
138137
}
139138

139+
// Build custom courseware registry
140+
const { allCourseWare, AllCourseWare } = await import('@vue-skuilder/courseware');
141+
const studioCourseWare = customQuestions
142+
? new AllCourseWare([...allCourseWare.courses, ...customQuestions.courses])
143+
: allCourseWare;
144+
145+
// Store custom courseware for use in components
146+
app.provide('studioCourseWare', studioCourseWare);
147+
140148
console.log('🎨 Studio Mode: Collecting view components');
141-
const viewComponents = Courses.allViewsRaw();
149+
const viewComponents = studioCourseWare.allViewsRaw();
142150
console.log(` ✅ Collected ${Object.keys(viewComponents).length} base view components`);
143151

144152
// Add custom question view components if available

packages/studio-ui/src/views/CreateCardView.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
:course-id="courseId"
3939
:course-cfg="courseConfig"
4040
:data-shape="selectedDataShape"
41-
:view-lookup-function="allCourseWare.getView"
41+
:view-lookup-function="studioCourseWare.getView"
42+
:course-ware="studioCourseWare"
4243
@card-created="onCardCreated"
4344
/>
4445

@@ -57,9 +58,9 @@
5758
</template>
5859

5960
<script setup lang="ts">
60-
import { ref, onMounted, computed } from 'vue';
61+
import { ref, onMounted, computed, inject } from 'vue';
6162
import { DataInputForm } from '@vue-skuilder/edit-ui';
62-
import { allCourseWare } from '@vue-skuilder/courseware';
63+
import { allCourseWare, AllCourseWare } from '@vue-skuilder/courseware';
6364
import { getStudioConfig, getConfigErrorMessage } from '../config/development';
6465
import { getDataLayer } from '@vue-skuilder/db';
6566
import type { CourseConfig, DataShape } from '@vue-skuilder/common';
@@ -71,6 +72,9 @@ const courseId = ref<string | null>(null);
7172
const courseConfig = ref<CourseConfig | null>(null);
7273
const selectedDataShapeIndex = ref<number>(0);
7374
75+
// Get custom courseware from app provider
76+
const studioCourseWare = inject<AllCourseWare>('studioCourseWare', allCourseWare);
77+
7478
// Get available data shapes
7579
const availableDataShapes = computed(() => {
7680
if (!courseConfig.value?.dataShapes) return [];
@@ -86,8 +90,8 @@ const selectedDataShape = computed((): DataShape | null => {
8690
const shapeName = shapes[selectedDataShapeIndex.value]?.name;
8791
if (!shapeName) return null;
8892
89-
// Search through all courses to find the DataShape
90-
for (const course of allCourseWare.courses) {
93+
// Search through all courses to find the DataShape
94+
for (const course of studioCourseWare.courses) {
9195
for (const question of course.questions) {
9296
for (const dataShape of question.dataShapes) {
9397
if (dataShape.name === shapeName.split('.').pop()) {

0 commit comments

Comments
 (0)