@@ -1472,6 +1472,13 @@ export class NavigationManager {
14721472 await this . populateSessionsTable ( e . target . value ) ;
14731473 } ) ;
14741474 }
1475+
1476+ const exportBtn = document . getElementById ( 'export-sessions-btn' ) ;
1477+ if ( exportBtn ) {
1478+ exportBtn . addEventListener ( 'click' , ( ) => {
1479+ this . exportSessionsToExcel ( ) ;
1480+ } ) ;
1481+ }
14751482 }
14761483
14771484 async populateSessionsTable ( period = 'today' ) {
@@ -1629,34 +1636,136 @@ export class NavigationManager {
16291636 async deleteSessionFromTable ( sessionId ) {
16301637 if ( ! window . sessionManager || ! sessionId ) return ;
16311638
1632- if ( confirm ( 'Are you sure you want to delete this session? This action cannot be undone.' ) ) {
1633- try {
1634- // Find and delete the session
1635- for ( const [ dateString , sessions ] of Object . entries ( window . sessionManager . sessions ) ) {
1636- const sessionIndex = sessions . findIndex ( s => s . id === sessionId ) ;
1637- if ( sessionIndex !== - 1 ) {
1638- sessions . splice ( sessionIndex , 1 ) ;
1639- await window . sessionManager . saveSessionsToStorage ( ) ;
1640-
1641- // Refresh the table
1642- const filterSelect = document . getElementById ( 'sessions-filter-period' ) ;
1643- const currentPeriod = filterSelect ? filterSelect . value : 'today' ;
1644- await this . populateSessionsTable ( currentPeriod ) ;
1639+ try {
1640+ // Find and delete the session
1641+ for ( const [ dateString , sessions ] of Object . entries ( window . sessionManager . sessions ) ) {
1642+ const sessionIndex = sessions . findIndex ( s => s . id === sessionId ) ;
1643+ if ( sessionIndex !== - 1 ) {
1644+ sessions . splice ( sessionIndex , 1 ) ;
1645+ await window . sessionManager . saveSessionsToStorage ( ) ;
1646+
1647+ // Refresh the table
1648+ const filterSelect = document . getElementById ( 'sessions-filter-period' ) ;
1649+ const currentPeriod = filterSelect ? filterSelect . value : 'today' ;
1650+ await this . populateSessionsTable ( currentPeriod ) ;
1651+
1652+ // Refresh other views
1653+ await this . updateDailyChart ( ) ;
1654+ await this . updateFocusSummary ( ) ;
1655+ await this . updateWeeklySessionsChart ( ) ;
1656+ await this . updateTimelineForDate ( new Date ( ) ) ;
1657+
1658+ console . log ( 'Session deleted successfully:' , sessionId ) ;
1659+ break ;
1660+ }
1661+ }
1662+ } catch ( error ) {
1663+ console . error ( 'Error deleting session:' , error ) ;
1664+ alert ( 'Failed to delete session. Please try again.' ) ;
1665+ }
1666+ }
1667+
1668+ async exportSessionsToExcel ( ) {
1669+ try {
1670+ const filterSelect = document . getElementById ( 'sessions-filter-period' ) ;
1671+ const currentPeriod = filterSelect ? filterSelect . value : 'today' ;
1672+ const sessions = this . getSessionsForPeriod ( currentPeriod ) ;
1673+
1674+ if ( sessions . length === 0 ) {
1675+ alert ( 'No sessions to export for the selected period.' ) ;
1676+ return ;
1677+ }
1678+
1679+ const XLSX = window . XLSX ;
1680+ if ( ! XLSX ) {
1681+ console . error ( 'XLSX library not found' ) ;
1682+ alert ( 'Excel export functionality is not available.' ) ;
1683+ return ;
1684+ }
1685+
1686+ // Prepare export data
1687+ const exportData = [ ] ;
1688+ for ( const session of sessions ) {
1689+ const sessionDate = new Date ( session . created_at ) ;
1690+ const formattedDate = sessionDate . toLocaleDateString ( 'en-US' , {
1691+ year : 'numeric' ,
1692+ month : '2-digit' ,
1693+ day : '2-digit'
1694+ } ) ;
1695+
1696+ const tags = await this . getSessionTags ( session . id ) ;
1697+ const tagNames = tags . map ( tag => tag . name ) . join ( ', ' ) ;
1698+
1699+ exportData . push ( {
1700+ 'Date' : formattedDate ,
1701+ 'Start Time' : session . start_time ,
1702+ 'End Time' : session . end_time ,
1703+ 'Duration (minutes)' : session . duration ,
1704+ 'Type' : session . session_type ,
1705+ 'Tags' : tagNames || '-' ,
1706+ 'Notes' : session . notes || '-'
1707+ } ) ;
1708+ }
1709+
1710+ exportData . sort ( ( a , b ) => {
1711+ const dateComparison = new Date ( b . Date ) . getTime ( ) - new Date ( a . Date ) . getTime ( ) ;
1712+ if ( dateComparison !== 0 ) return dateComparison ;
1713+ return b [ 'Start Time' ] . localeCompare ( a [ 'Start Time' ] ) ;
1714+ } ) ;
1715+
1716+ // Create Excel workbook
1717+ const ws = XLSX . utils . json_to_sheet ( exportData ) ;
1718+ const wb = XLSX . utils . book_new ( ) ;
1719+ XLSX . utils . book_append_sheet ( wb , ws , 'Session History' ) ;
1720+
1721+ // Generate default filename
1722+ const today = new Date ( ) ;
1723+ const dateStr = today . toISOString ( ) . split ( 'T' ) [ 0 ] ;
1724+ const defaultFilename = `presto-session-history-${ currentPeriod } -${ dateStr } .xlsx` ;
1725+
1726+ // Check if we're in Tauri environment
1727+ if ( window . __TAURI__ ) {
1728+ try {
1729+ // Use Tauri's save dialog
1730+ const filePath = await window . __TAURI__ . dialog . save ( {
1731+ defaultPath : defaultFilename ,
1732+ filters : [ {
1733+ name : 'Excel files' ,
1734+ extensions : [ 'xlsx' ]
1735+ } ]
1736+ } ) ;
1737+
1738+ if ( filePath ) {
1739+ // Convert workbook to base64 for Tauri
1740+ const wbout = XLSX . write ( wb , { bookType : 'xlsx' , type : 'base64' } ) ;
16451741
1646- // Refresh other views
1647- await this . updateDailyChart ( ) ;
1648- await this . updateFocusSummary ( ) ;
1649- await this . updateWeeklySessionsChart ( ) ;
1650- await this . updateTimelineForDate ( new Date ( ) ) ;
1742+ // Use invoke to call Rust backend to save file
1743+ await window . __TAURI__ . core . invoke ( 'write_excel_file' , {
1744+ path : filePath ,
1745+ data : wbout
1746+ } ) ;
16511747
1652- console . log ( 'Session deleted successfully:' , sessionId ) ;
1653- break ;
1748+ console . log ( `Exported ${ sessions . length } sessions to ${ filePath } ` ) ;
1749+ alert ( `Sessions exported successfully to:\n${ filePath } ` ) ;
1750+ } else {
1751+ console . log ( 'Export cancelled by user' ) ;
16541752 }
1753+ } catch ( tauriError ) {
1754+ console . error ( 'Tauri save error:' , tauriError ) ;
1755+ // Fallback to direct download
1756+ XLSX . writeFile ( wb , defaultFilename ) ;
1757+ console . log ( `Tauri save failed, using fallback download: ${ defaultFilename } ` ) ;
1758+ alert ( `File saved to Downloads folder as: ${ defaultFilename } ` ) ;
16551759 }
1656- } catch ( error ) {
1657- console . error ( 'Error deleting session:' , error ) ;
1658- alert ( 'Failed to delete session. Please try again.' ) ;
1760+ } else {
1761+ // Fallback for web environment - direct download
1762+ XLSX . writeFile ( wb , defaultFilename ) ;
1763+ console . log ( `Exported ${ sessions . length } sessions to ${ defaultFilename } ` ) ;
16591764 }
1765+
1766+ } catch ( error ) {
1767+ console . error ( 'Error exporting sessions:' , error ) ;
1768+ alert ( 'Failed to export sessions. Please try again.' ) ;
16601769 }
16611770 }
16621771}
0 commit comments