merge: R4 TypeScript hardening H1-H6 — reduce errors 177→152 (resolve cc-graph-shapes/CCGraphNavPanel conflicts with R3)

This commit is contained in:
CC Worker 2026-06-01 02:38:50 +00:00
commit f7bb84f9b8
11 changed files with 43 additions and 24 deletions

View File

@ -23,6 +23,7 @@ export type LogCategory =
| 'neo-institute-context'
| 'auth-service'
| 'graph-service'
| 'graph-sidebar'
| 'registration-service'
| 'provisioning-service'
| 'snapshot-service'

View File

@ -31,6 +31,7 @@ import {
} from '@mui/material';
import {
CloudUpload as UploadIcon,
Upload,
Folder as FolderIcon,
FolderOpen as FolderOpenIcon,
Description as FileIcon,
@ -39,8 +40,12 @@ import {
PlayArrow as ProcessIcon,
CheckCircle as SuccessIcon,
Error as ErrorIcon,
Info as InfoIcon
Info as InfoIcon,
InsertDriveFile,
} from '@mui/icons-material';
const FolderOpen = FolderOpenIcon;
const Refresh = RefreshIcon;
const Info = InfoIcon;
import { supabase } from '../../supabaseClient';
import {
pickDirectory,

View File

@ -73,8 +73,9 @@ export function CCExportPdfButton({ editor, pdf }: CCExportPdfButtonProps) {
tickProgress();
}
const pdfBytes = await pdf.save();
const url = URL.createObjectURL(
new Blob([await pdf.save()], { type: 'application/pdf' })
new Blob([pdfBytes.buffer as ArrayBuffer], { type: 'application/pdf' })
);
tickProgress();

View File

@ -17,10 +17,16 @@ export class CCTimetableLessonNodeShapeUtil extends CCBaseShapeUtil<CCTimetableL
getDefaultProps(): CCTimetableLessonNodeShape['props'] {
const defaultProps = getDefaultCCTimetableLessonNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTimetableLessonNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
headerColor: '',
school_db_name: '',
school_period_id: '',
subject_class: '',
date: '',
start_time: '',
end_time: '',
period_code: '',
}
}
@ -29,34 +35,34 @@ export class CCTimetableLessonNodeShapeUtil extends CCBaseShapeUtil<CCTimetableL
renderContent = (shape: CCTimetableLessonNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
<NodeProperty
label="Subject Class"
value={shape.props.subject_class}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
@ -65,4 +71,4 @@ export class CCTimetableLessonNodeShapeUtil extends CCBaseShapeUtil<CCTimetableL
</div>
)
}
}
}

View File

@ -543,6 +543,8 @@ export const getDefaultCCTimetableLessonNodeProps = () => ({
start_time: '',
end_time: '',
period_code: '',
school_db_name: '',
school_period_id: '',
})
export const getDefaultCCPlannedLessonNodeProps = () => ({

View File

@ -22,7 +22,6 @@ import { CCSubjectNodeShape, CCSubjectNodeShapeUtil } from './CCSubjectNodeShape
import { CCTopicNodeShape, CCTopicNodeShapeUtil } from './CCTopicNodeShapeUtil'
import { CCTopicLessonNodeShape, CCTopicLessonNodeShapeUtil } from './CCTopicLessonNodeShapeUtil'
import { CCLearningStatementNodeShape, CCLearningStatementNodeShapeUtil } from './CCLearningStatementNodeShapeUtil'
import { CCScienceLabNodeShape, CCScienceLabNodeShapeUtil } from './CCScienceLabNodeShapeUtil'
import { CCSchoolTimetableNodeShape, CCSchoolTimetableNodeShapeUtil } from './CCSchoolTimetableNodeShapeUtil'
import { CCAcademicYearNodeShape, CCAcademicYearNodeShapeUtil } from './CCAcademicYearNodeShapeUtil'
import { CCAcademicTermNodeShape, CCAcademicTermNodeShapeUtil } from './CCAcademicTermNodeShapeUtil'
@ -31,11 +30,11 @@ import { CCAcademicDayNodeShape, CCAcademicDayNodeShapeUtil } from './CCAcademic
import { CCAcademicPeriodNodeShape, CCAcademicPeriodNodeShapeUtil } from './CCAcademicPeriodNodeShapeUtil'
import { CCRegistrationPeriodNodeShape, CCRegistrationPeriodNodeShapeUtil } from './CCRegistrationPeriodNodeShapeUtil'
import { CCTeacherTimetableNodeShape, CCTeacherTimetableNodeShapeUtil } from './CCTeacherTimetableNodeShapeUtil'
import { CCTimetableLessonNodeShape, CCTimetableLessonNodeShapeUtil } from './CCTimetableLessonNodeShapeUtil'
import { CCPlannedLessonNodeShape, CCPlannedLessonNodeShapeUtil } from './CCPlannedLessonNodeShapeUtil'
import { CCDepartmentStructureNodeShape, CCDepartmentStructureNodeShapeUtil } from './CCDepartmentStructureNodeShapeUtil'
import { CCUserTeacherTimetableNodeShape, CCUserTeacherTimetableNodeShapeUtil } from './CCUserTeacherTimetableNodeShapeUtil'
import { CCTimetableLessonNodeShape, CCTimetableLessonNodeShapeUtil } from './CCUserTimetableLessonNodeShapeUtil'
import { CCScienceLabNodeShape, CCScienceLabNodeShapeUtil } from './CCScienceLabNodeShapeUtil'
// Create a const object with all node types
export const NODE_SHAPE_TYPES = {
USER: CCUserNodeShapeUtil.type,

View File

@ -27,8 +27,8 @@ export class TranscriptionManager {
this.transcriptionService = new TranscriptionService();
// Set up callback for transcription updates
this.transcriptionService.setTranscriptionCallback((text: string, isFinal: boolean, metadata: { start: number, end: number }) => {
console.log('📝 Transcription update received:', { text, metadata });
this.transcriptionService.setServerSegmentsCallback((segments: Array<{ text: string; start: number; end: number }>, isLastLive: boolean) => {
console.log('📝 Transcription update received:', { segments: segments.length, isLastLive });
const util = this.editor.getShapeUtil<CCLiveTranscriptionShapeUtil>('cc-live-transcription');
if (!util) {
console.warn('❌ Shape util not found');
@ -36,6 +36,10 @@ export class TranscriptionManager {
}
console.log('Found transcription util:', !!util);
const text = segments.map(s => s.text).join('') || '';
const metadata = segments.length ? { start: segments[0].start, end: segments[segments.length - 1].end } : { start: 0, end: 0 };
const isFinal = isLastLive;
// Check if text is stable (same output multiple times)
const isStable = text === this.lastText;
if (isStable) {

View File

@ -200,7 +200,7 @@ export const CCExamMarkerPanel: React.FC<CCExamMarkerPanelProps> = ({
const pdfBytes = await newPdf.save();
const url = URL.createObjectURL(
new Blob([pdfBytes], { type: 'application/pdf' })
new Blob([pdfBytes] as unknown as BlobPart[], { type: 'application/pdf' })
);
tickProgress();
@ -297,7 +297,7 @@ export const CCExamMarkerPanel: React.FC<CCExamMarkerPanelProps> = ({
// Save the combined PDF
const pdfBytes = await newPdf.save();
const url = URL.createObjectURL(new Blob([pdfBytes], { type: 'application/pdf' }));
const url = URL.createObjectURL(new Blob([pdfBytes] as unknown as BlobPart[], { type: 'application/pdf' }));
const a = document.createElement('a');
a.href = url;
a.download = currentPdf.name;

View File

@ -346,9 +346,10 @@ export const CCFilesPanelEnhanced: React.FC = () => {
ref={dirInputRef}
type="file"
style={{ display: 'none' }}
webkitdirectory=""
multiple
multiple
onChange={handleFallbackDirectorySelect}
// @ts-ignore WebKit directory picker attribute for folder upload
webkitdirectory=""
/>
<Tooltip title={isDirectoryPickerSupported() ? "Uses modern directory picker" : "Uses fallback method"}>

View File

@ -518,7 +518,7 @@ export function CCGraphNavPanel() {
const data = await res.json();
setTree(data.tree);
} catch (err) {
logger.error('graph-panel', 'Failed to load graph tree', err);
logger.error('navigation-panel', 'Failed to load graph tree', err);
setError('Failed to load navigation tree');
} finally {
setLoading(false);
@ -650,12 +650,12 @@ export function CCGraphNavPanel() {
}, []);
const handleCalendarWizardComplete = useCallback(() => {
logger.info('graph-panel', 'School calendar setup complete');
logger.info('navigation-panel', 'School calendar setup complete');
refreshAll();
}, [refreshAll]);
const handleTimetableWizardComplete = useCallback((timetableId: string) => {
logger.info('graph-panel', 'Teacher timetable setup complete', { timetableId });
logger.info('navigation-panel', 'Teacher timetable setup complete', { timetableId });
refreshAll();
}, [refreshAll]);

View File

@ -1,7 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react';
import { Box, Typography, styled, Button, ThemeProvider, createTheme, useMediaQuery } from '@mui/material';
import Save from '@mui/icons-material/Save';
import Reset from '@mui/icons-material/RestartAlt';
import { RestartAlt } from '@mui/icons-material';
import { useEditor, useToasts, loadSnapshot } from '@tldraw/tldraw';
import { useNavigationStore } from '../../../../../../stores/navigationStore';
import { useAuth } from '../../../../../../contexts/AuthContext';