@package-uploader/ui 1.1.4 → 1.1.5
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/assets/index-BtMbH61W.js +71 -0
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/api/client.ts +4 -2
- package/src/components/UploadModal.tsx +55 -22
- package/dist/assets/index-CAZIUAbb.js +0 -71
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Package Uploader</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BtMbH61W.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-DHoRoGws.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/package.json
CHANGED
package/src/api/client.ts
CHANGED
|
@@ -294,10 +294,12 @@ export const api = {
|
|
|
294
294
|
getLaunchUrl: (documentId: number) =>
|
|
295
295
|
request<{ url: string }>('GET', `/documents/${documentId}/launch`),
|
|
296
296
|
|
|
297
|
-
// Preview: extract SCORM ZIP to temp dir with bridge script for live preview
|
|
298
|
-
startPreview: async (file: File): Promise<{ token: string; url: string }> => {
|
|
297
|
+
// Preview: patch + extract SCORM ZIP to temp dir with bridge script for live preview
|
|
298
|
+
startPreview: async (file: File, options?: { skin?: string; classMappings?: CourseClassMappings }): Promise<{ token: string; url: string }> => {
|
|
299
299
|
const formData = new FormData();
|
|
300
300
|
formData.append('file', file);
|
|
301
|
+
if (options?.skin) formData.append('skin', options.skin);
|
|
302
|
+
if (options?.classMappings) formData.append('classMappings', JSON.stringify(options.classMappings));
|
|
301
303
|
return request<{ token: string; url: string }>('POST', '/preview', formData);
|
|
302
304
|
},
|
|
303
305
|
|
|
@@ -135,6 +135,12 @@ export default function UploadModal({
|
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
// Already parsed but no preview — toggle panel off (clear structure to collapse)
|
|
139
|
+
if (courseStructure) {
|
|
140
|
+
setCourseStructure(null);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
138
144
|
// Already failed — don't retry
|
|
139
145
|
if (parseFailed) return;
|
|
140
146
|
|
|
@@ -144,30 +150,40 @@ export default function UploadModal({
|
|
|
144
150
|
setParsingStructure(true);
|
|
145
151
|
setPreviewLoading(true);
|
|
146
152
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
]);
|
|
155
|
-
|
|
156
|
-
if (structure) {
|
|
157
|
-
setCourseStructure(structure);
|
|
158
|
-
setParseFailed(false);
|
|
159
|
-
setPreviewToken(preview.token);
|
|
160
|
-
setPreviewUrl(preview.url);
|
|
161
|
-
} else {
|
|
162
|
-
setParseFailed(true);
|
|
163
|
-
// Cleanup the preview if structure parse failed
|
|
164
|
-
api.stopPreview(preview.token).catch(() => {});
|
|
153
|
+
// Parse structure first — this determines if we can proceed
|
|
154
|
+
let structure = courseStructure;
|
|
155
|
+
if (!structure) {
|
|
156
|
+
try {
|
|
157
|
+
structure = await api.parseCourseStructure(files[0].file);
|
|
158
|
+
} catch {
|
|
159
|
+
structure = null;
|
|
165
160
|
}
|
|
166
|
-
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!structure) {
|
|
167
164
|
setParseFailed(true);
|
|
165
|
+
setParsingStructure(false);
|
|
166
|
+
setPreviewLoading(false);
|
|
167
|
+
return;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
setCourseStructure(structure);
|
|
171
|
+
setParseFailed(false);
|
|
170
172
|
setParsingStructure(false);
|
|
173
|
+
|
|
174
|
+
// Start preview independently — patches with current skin + classMappings
|
|
175
|
+
try {
|
|
176
|
+
const previewOptions: { skin?: string; classMappings?: CourseClassMappings } = {};
|
|
177
|
+
if (skinName.trim()) previewOptions.skin = skinName.trim();
|
|
178
|
+
if (Object.keys(classMappings).length > 0) previewOptions.classMappings = classMappings;
|
|
179
|
+
const preview = await api.startPreview(files[0].file, previewOptions);
|
|
180
|
+
setPreviewToken(preview.token);
|
|
181
|
+
setPreviewUrl(preview.url);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
console.warn('Preview not available:', err);
|
|
184
|
+
// Preview failed but structure is valid — stay in non-preview mode
|
|
185
|
+
}
|
|
186
|
+
|
|
171
187
|
setPreviewLoading(false);
|
|
172
188
|
}
|
|
173
189
|
|
|
@@ -334,6 +350,8 @@ export default function UploadModal({
|
|
|
334
350
|
? 'Not a Rise course'
|
|
335
351
|
: isPreviewMode
|
|
336
352
|
? 'Close Preview'
|
|
353
|
+
: courseStructure
|
|
354
|
+
? `Customize Classes (${courseStructure.lessons.length} lessons)`
|
|
337
355
|
: 'Customize Classes';
|
|
338
356
|
|
|
339
357
|
// Build the preview URL — needs the API base path prepended
|
|
@@ -542,20 +560,35 @@ export default function UploadModal({
|
|
|
542
560
|
</div>
|
|
543
561
|
)}
|
|
544
562
|
|
|
545
|
-
{/* Customize Classes button */}
|
|
563
|
+
{/* Customize Classes button + panel */}
|
|
546
564
|
{isSingleFile && !uploading && (
|
|
547
565
|
<div className="structure-section">
|
|
548
566
|
<button
|
|
549
|
-
className={`structure-toggle-btn${parseFailed ? ' disabled' : ''}`}
|
|
567
|
+
className={`structure-toggle-btn${courseStructure && !isPreviewMode ? ' open' : ''}${parseFailed ? ' disabled' : ''}`}
|
|
550
568
|
onClick={handleCustomizeClick}
|
|
551
569
|
disabled={parsingStructure || parseFailed}
|
|
552
570
|
>
|
|
553
571
|
{parsingStructure && <div className="spinner" />}
|
|
554
572
|
<span>{customizeLabel}</span>
|
|
555
|
-
{
|
|
573
|
+
{!parsingStructure && !parseFailed && courseStructure && (
|
|
574
|
+
<span className="structure-toggle-arrow">
|
|
575
|
+
{courseStructure && !isPreviewMode ? '\u25B2' : '\u25BC'}
|
|
576
|
+
</span>
|
|
577
|
+
)}
|
|
578
|
+
{assignmentCount > 0 && !courseStructure && (
|
|
556
579
|
<span className="course-structure-badge">{assignmentCount} assigned</span>
|
|
557
580
|
)}
|
|
558
581
|
</button>
|
|
582
|
+
|
|
583
|
+
{courseStructure && !isPreviewMode && (
|
|
584
|
+
<div className="structure-panel">
|
|
585
|
+
<CourseStructureStep
|
|
586
|
+
structure={courseStructure}
|
|
587
|
+
classMappings={classMappings}
|
|
588
|
+
onChange={setClassMappings}
|
|
589
|
+
/>
|
|
590
|
+
</div>
|
|
591
|
+
)}
|
|
559
592
|
</div>
|
|
560
593
|
)}
|
|
561
594
|
|