@@ -536,6 +536,8 @@ export class Job extends Session {
536536 target_storage : Storage ,
537537 parent_job_id : number | null ;
538538 consensus_replicas : number ;
539+ // Save 버튼 클릭 시 FE에서 BE로 전달되는 마지막 프레임 번호
540+ last_frame : number | null ;
539541 } ;
540542
541543 constructor ( initialData : InitializerType ) {
@@ -566,6 +568,8 @@ export class Job extends Session {
566568 target_storage : undefined ,
567569 parent_job_id : null ,
568570 consensus_replicas : undefined ,
571+ // Save하기 전에는 null로 초기화
572+ last_frame : null ,
569573 } ;
570574
571575 this . #data. id = initialData . id ?? this . #data. id ;
@@ -583,6 +587,10 @@ export class Job extends Session {
583587 this . #data. created_date = initialData . created_date ?? this . #data. created_date ;
584588 this . #data. parent_job_id = initialData . parent_job_id ?? this . #data. parent_job_id ;
585589 this . #data. consensus_replicas = initialData . consensus_replicas ?? this . #data. consensus_replicas ;
590+ // last_frame은 undefined는 무시, null은 '새 저장 없음' 의미로 유지
591+ if ( initialData . last_frame !== undefined ) {
592+ this . #data. last_frame = initialData . last_frame ;
593+ }
586594
587595 if ( Array . isArray ( initialData . labels ) ) {
588596 this . #data. labels = initialData . labels . map ( ( labelData ) => {
@@ -637,6 +645,10 @@ export class Job extends Session {
637645 this . #data. guide_id = data . guide_id ?? this . #data. guide_id ;
638646 this . #data. updated_date = data . updated_date ?? this . #data. updated_date ;
639647 this . #data. bug_tracker = data . bug_tracker ?? this . #data. bug_tracker ;
648+ // reinit 시에도 last_frame 동기화 (save 후 응답에서 갱신)
649+ if ( data . last_frame !== undefined ) {
650+ this . #data. last_frame = data . last_frame ;
651+ }
640652
641653 // TODO: labels also may get changed, but it will affect many code within the application
642654 // so, need to think on this additionally
@@ -730,6 +742,21 @@ export class Job extends Session {
730742 return this . #data. updated_date ;
731743 }
732744
745+ // Save 버튼으로 저장된 마지막 프레임 번호. null이면 아직 Save한 적 없는 Job
746+ public get lastFrame ( ) : number | null {
747+ return this . #data. last_frame ;
748+ }
749+
750+ // last_frame 기반으로 계산한 진행율 (0~100, 정수). null이면 미표시
751+ public get annotationProgress ( ) : number | null {
752+ if ( this . #data. last_frame == null ) return null ;
753+ const totalFrames = this . #data. stop_frame - this . #data. start_frame + 1 ;
754+ if ( totalFrames <= 0 ) return null ;
755+ return Math . round (
756+ ( ( this . #data. last_frame - this . #data. start_frame + 1 ) / totalFrames ) * 100
757+ ) ;
758+ }
759+
733760 public get sourceStorage ( ) : Storage {
734761 return this . #data. source_storage ;
735762 }
@@ -955,6 +982,8 @@ export class Task extends Session {
955982 source_storage : initialData . source_storage ,
956983 parent_job_id : job . parent_job_id ,
957984 consensus_replicas : job . consensus_replicas ,
985+ // Task API 응답의 embedded jobs에도 last_frame 전달 (job-item 진행율 표시용)
986+ last_frame : job . last_frame ,
958987 } ) ;
959988 data . jobs . push ( jobInstance ) ;
960989 }
0 commit comments