@package-uploader/ui 1.1.4 → 1.1.6
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/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-BS61yFPt.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,34 @@ export default function UploadModal({
|
|
|
144
150
|
setParsingStructure(true);
|
|
145
151
|
setPreviewLoading(true);
|
|
146
152
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
])
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
setPreviewUrl(preview.url);
|
|
161
|
-
} else {
|
|
162
|
-
setParseFailed(true);
|
|
163
|
-
// Cleanup the preview if structure parse failed
|
|
164
|
-
api.stopPreview(preview.token).catch(() => {});
|
|
165
|
-
}
|
|
166
|
-
} catch {
|
|
153
|
+
// Run parse + preview in parallel — preview shows immediately with loading spinner
|
|
154
|
+
const previewOptions: { skin?: string; classMappings?: CourseClassMappings } = {};
|
|
155
|
+
if (skinName.trim()) previewOptions.skin = skinName.trim();
|
|
156
|
+
if (Object.keys(classMappings).length > 0) previewOptions.classMappings = classMappings;
|
|
157
|
+
|
|
158
|
+
const [structure, preview] = await Promise.all([
|
|
159
|
+
api.parseCourseStructure(files[0].file).catch(() => null),
|
|
160
|
+
api.startPreview(files[0].file, previewOptions).catch(() => null),
|
|
161
|
+
]);
|
|
162
|
+
|
|
163
|
+
setParsingStructure(false);
|
|
164
|
+
|
|
165
|
+
if (!structure) {
|
|
167
166
|
setParseFailed(true);
|
|
167
|
+
setPreviewLoading(false);
|
|
168
|
+
// Clean up preview if it succeeded but parse didn't
|
|
169
|
+
if (preview?.token) api.stopPreview(preview.token).catch(() => {});
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
setCourseStructure(structure);
|
|
174
|
+
setParseFailed(false);
|
|
175
|
+
|
|
176
|
+
if (preview) {
|
|
177
|
+
setPreviewToken(preview.token);
|
|
178
|
+
setPreviewUrl(preview.url);
|
|
168
179
|
}
|
|
169
180
|
|
|
170
|
-
setParsingStructure(false);
|
|
171
181
|
setPreviewLoading(false);
|
|
172
182
|
}
|
|
173
183
|
|
|
@@ -334,7 +344,9 @@ export default function UploadModal({
|
|
|
334
344
|
? 'Not a Rise course'
|
|
335
345
|
: isPreviewMode
|
|
336
346
|
? 'Close Preview'
|
|
337
|
-
:
|
|
347
|
+
: courseStructure
|
|
348
|
+
? `Customize Course (${courseStructure.lessons.length} lessons)`
|
|
349
|
+
: 'Customize Course';
|
|
338
350
|
|
|
339
351
|
// Build the preview URL — needs the API base path prepended
|
|
340
352
|
const fullPreviewUrl = previewUrl
|
|
@@ -542,20 +554,35 @@ export default function UploadModal({
|
|
|
542
554
|
</div>
|
|
543
555
|
)}
|
|
544
556
|
|
|
545
|
-
{/* Customize Classes button */}
|
|
557
|
+
{/* Customize Classes button + panel */}
|
|
546
558
|
{isSingleFile && !uploading && (
|
|
547
559
|
<div className="structure-section">
|
|
548
560
|
<button
|
|
549
|
-
className={`structure-toggle-btn${parseFailed ? ' disabled' : ''}`}
|
|
561
|
+
className={`structure-toggle-btn${courseStructure && !isPreviewMode ? ' open' : ''}${parseFailed ? ' disabled' : ''}`}
|
|
550
562
|
onClick={handleCustomizeClick}
|
|
551
563
|
disabled={parsingStructure || parseFailed}
|
|
552
564
|
>
|
|
553
565
|
{parsingStructure && <div className="spinner" />}
|
|
554
566
|
<span>{customizeLabel}</span>
|
|
555
|
-
{
|
|
567
|
+
{!parsingStructure && !parseFailed && courseStructure && (
|
|
568
|
+
<span className="structure-toggle-arrow">
|
|
569
|
+
{courseStructure && !isPreviewMode ? '\u25B2' : '\u25BC'}
|
|
570
|
+
</span>
|
|
571
|
+
)}
|
|
572
|
+
{assignmentCount > 0 && !courseStructure && (
|
|
556
573
|
<span className="course-structure-badge">{assignmentCount} assigned</span>
|
|
557
574
|
)}
|
|
558
575
|
</button>
|
|
576
|
+
|
|
577
|
+
{courseStructure && !isPreviewMode && (
|
|
578
|
+
<div className="structure-panel">
|
|
579
|
+
<CourseStructureStep
|
|
580
|
+
structure={courseStructure}
|
|
581
|
+
classMappings={classMappings}
|
|
582
|
+
onChange={setClassMappings}
|
|
583
|
+
/>
|
|
584
|
+
</div>
|
|
585
|
+
)}
|
|
559
586
|
</div>
|
|
560
587
|
)}
|
|
561
588
|
|