22import React , { useRef , useState } from "react" ;
33import * as XLSX from "xlsx" ;
44import { toast } from "react-toastify" ;
5- import { Download , Loader2 , Save , UploadCloud } from "lucide-react" ;
5+ import { Download , Loader2 , UploadCloud } from "lucide-react" ;
66import type { Project , Task , TeamMember } from "../types" ;
77import {
88 findDataUrisInHtml ,
99 replaceDataUrisInCommentsAndUpload ,
1010 replaceDataUrisInHtmlAndUpload ,
1111} from "../utils/dataURItoFile" ;
12+ import { useStoreWorkspace } from "../utils/store" ;
1213
1314/**
1415 * ExportImportControls (per-project)
1516 *
1617 * Props:
17- * - projects: Project[] (used only to resolve project -> workspaceId if selectedProjectId provided)
18+ * - projects: Project[] (used only to resolve project -> workspaceId if projectId provided)
1819 * - tasks: Task[]
1920 * - team: TeamMember[]
20- * - selectedProjectId ?: string // when provided, export only tasks for this project (and related members)
21+ * - projectId ?: string // when provided, export only tasks for this project (and related members)
2122 * - onImport: (payload: { tasks?: Task[]; team?: TeamMember[] }) => void
2223 *
2324 * Exports sheets:
@@ -31,18 +32,18 @@ export default function ExportImportControls({
3132 projects,
3233 tasks,
3334 team,
34- selectedProjectId,
3535 onImport,
3636} : {
3737 projects ?: Project [ ] ;
3838 tasks : Task [ ] ;
3939 team : TeamMember [ ] ;
40- selectedProjectId ?: string ;
4140 onImport : ( payload : { tasks ?: Task [ ] ; team ?: TeamMember [ ] } ) => void ;
4241} ) {
4342 const fileRef = useRef < HTMLInputElement | null > ( null ) ;
4443 const [ isLoading , setIsLoading ] = useState < boolean > ( false ) ;
4544
45+ const { workspaceId, projectId } = useStoreWorkspace ( ) ;
46+
4647 const safeString = ( v : any ) =>
4748 v === null || typeof v === "undefined" ? "" : String ( v ) ;
4849 const tryParseJSON = ( s : string ) => {
@@ -55,7 +56,15 @@ export default function ExportImportControls({
5556
5657 async function exportXlsx ( ) {
5758 try {
59+ if ( ! projectId ) {
60+
61+ toast . dark (
62+ `Warning: Failed export task. Project ID not found!`
63+ ) ;
64+ return
65+ }
5866 setIsLoading ( true ) ;
67+
5968 const MAX_EXCEL_CELL = 32767 ; // Excel limit for a single cell
6069 const truncations : string [ ] = [ ] ;
6170
@@ -71,8 +80,8 @@ export default function ExportImportControls({
7180 } ;
7281
7382 // Determine tasks to export (per-project if selected)
74- const filteredTasks = selectedProjectId
75- ? tasks . filter ( ( t ) => t . projectId === selectedProjectId )
83+ const filteredTasks = projectId
84+ ? tasks . filter ( ( t ) => t . projectId === projectId )
7685 : tasks . slice ( ) ;
7786
7887 // ---------------------------
@@ -101,8 +110,7 @@ export default function ExportImportControls({
101110 err
102111 ) ;
103112 toast . dark (
104- `Warning: failed uploading embedded files for comments on task ${
105- t . id ?? ""
113+ `Warning: failed uploading embedded files for comments on task ${ t . id ?? ""
106114 } `
107115 ) ;
108116 }
@@ -144,8 +152,7 @@ export default function ExportImportControls({
144152 err
145153 ) ;
146154 toast . dark (
147- `Warning: failed uploading embedded files for description on task ${
148- t . id ?? ""
155+ `Warning: failed uploading embedded files for description on task ${ t . id ?? ""
149156 } `
150157 ) ;
151158 // keep original description if upload fails (don't block export)
@@ -160,7 +167,7 @@ export default function ExportImportControls({
160167 }
161168
162169 // Try to find project's workspaceId for broader team inclusion (optional)
163- const project = projects ?. find ( ( p ) => p . id === selectedProjectId ) ;
170+ const project = projects ?. find ( ( p ) => p . id === projectId ) ;
164171 const projectWorkspaceId = project ?. workspaceId ;
165172
166173 // Build a map for quick lookup of member email by id
@@ -174,7 +181,7 @@ export default function ExportImportControls({
174181 if ( assigneeIds . size > 0 && assigneeIds . has ( m . id ) ) return true ;
175182 if ( projectWorkspaceId && m . workspaceId === projectWorkspaceId )
176183 return true ;
177- return ! selectedProjectId ;
184+ return ! projectId ;
178185 } )
179186 . map ( ( m ) => ( {
180187 id : truncateForExcel ( m . id ?? "" , `team.id:${ m . id ?? "" } ` ) ,
@@ -292,7 +299,7 @@ export default function ExportImportControls({
292299 "team"
293300 ) ;
294301
295- const projectTag = selectedProjectId ? `_${ selectedProjectId } ` : "" ;
302+ const projectTag = projectId ? `_${ projectId } ` : "" ;
296303 const filename = `commitflow_export${ projectTag } _${ new Date ( )
297304 . toISOString ( )
298305 . slice ( 0 , 10 ) } .xlsx`;
@@ -324,6 +331,15 @@ export default function ExportImportControls({
324331 function onFileChange ( e : React . ChangeEvent < HTMLInputElement > ) {
325332 const f = e . target . files ?. [ 0 ] ;
326333 if ( ! f ) return ;
334+
335+ if ( ! projectId ) {
336+
337+ toast . dark (
338+ `Warning: Failed import task. Project ID not found!`
339+ ) ;
340+ return
341+ }
342+
327343 setIsLoading ( true ) ;
328344 const reader = new FileReader ( ) ;
329345 reader . onload = async ( ev ) => {
0 commit comments