@@ -1116,6 +1116,24 @@ class PowerToolsUI {
11161116 </label>
11171117 </div>
11181118 </div>
1119+
1120+ <div class="preferences-section">
1121+ <h3>Data Management</h3>
1122+ <div class="data-management-buttons">
1123+ <button class="power-tools-btn export-btn" id="export-settings-btn">
1124+ <span class="codicon codicon-export"></span>
1125+ Export Settings
1126+ </button>
1127+ <button class="power-tools-btn import-btn" id="import-settings-btn">
1128+ <span class="codicon codicon-import"></span>
1129+ Import Settings
1130+ </button>
1131+ <input type="file" id="import-file-input" accept=".json" style="display: none;">
1132+ </div>
1133+ <div class="data-management-info">
1134+ <p>Export your complete Power Tools configuration (templates, categories, and preferences) to a JSON file for backup or sharing.</p>
1135+ </div>
1136+ </div>
11191137 </div>
11201138 </div>
11211139 </div>
@@ -1493,8 +1511,9 @@ class PowerToolsUI {
14931511
14941512 .template-category-count {
14951513 font-size: 11px;
1496- color: var(--vscode-descriptionForeground, #888);
1497- background: var(--vscode-badge-background, #4d4d4d);
1514+ color: rgb(255 255 255);
1515+ background: #0099cc;
1516+ font-weight: bold;
14981517 padding: 2px 6px;
14991518 border-radius: 10px;
15001519 min-width: 16px;
@@ -1703,6 +1722,58 @@ class PowerToolsUI {
17031722 height: 16px;
17041723 }
17051724
1725+ /* Data Management Section */
1726+ .data-management-buttons {
1727+ display: flex;
1728+ gap: 12px;
1729+ margin-bottom: 16px;
1730+ }
1731+
1732+ .export-btn, .import-btn {
1733+ display: flex;
1734+ align-items: center;
1735+ gap: 8px;
1736+ padding: 8px 16px;
1737+ font-size: 13px;
1738+ border-radius: 3px;
1739+ border: 1px solid var(--vscode-button-border, transparent);
1740+ cursor: pointer;
1741+ transition: all 0.2s ease;
1742+ }
1743+
1744+ .export-btn {
1745+ background-color: var(--vscode-button-background, #0e639c);
1746+ color: var(--vscode-button-foreground, #ffffff);
1747+ }
1748+
1749+ .export-btn:hover {
1750+ background-color: var(--vscode-button-hoverBackground, #1177bb);
1751+ }
1752+
1753+ .import-btn {
1754+ background-color: var(--vscode-button-secondaryBackground, #3c3c3c);
1755+ color: var(--vscode-button-secondaryForeground, #cccccc);
1756+ }
1757+
1758+ .import-btn:hover {
1759+ background-color: var(--vscode-button-secondaryHoverBackground, #505050);
1760+ }
1761+
1762+ .data-management-info {
1763+ padding: 12px;
1764+ background-color: var(--vscode-textBlockQuote-background, #1e1e1e);
1765+ border: 1px solid var(--vscode-textBlockQuote-border, #007acc);
1766+ border-radius: 3px;
1767+ margin-top: 8px;
1768+ }
1769+
1770+ .data-management-info p {
1771+ margin: 0;
1772+ font-size: 12px;
1773+ color: var(--vscode-descriptionForeground, #cccccc);
1774+ line-height: 1.4;
1775+ }
1776+
17061777 /* Modal Scrollbar Styles */
17071778 .power-tools-tab-content::-webkit-scrollbar,
17081779 .templates-list::-webkit-scrollbar,
@@ -2348,6 +2419,16 @@ class PowerToolsUI {
23482419 const restoreCategoryBtn = modal . querySelector ( '#restore-category-defaults-btn' ) ;
23492420 restoreCategoryBtn ?. addEventListener ( 'click' , ( ) => this . showRestoreCategoryDefaultsDialog ( modal ) ) ;
23502421
2422+ // Export settings button
2423+ const exportBtn = modal . querySelector ( '#export-settings-btn' ) ;
2424+ exportBtn ?. addEventListener ( 'click' , ( ) => this . exportSettings ( ) ) ;
2425+
2426+ // Import settings button
2427+ const importBtn = modal . querySelector ( '#import-settings-btn' ) ;
2428+ const fileInput = modal . querySelector ( '#import-file-input' ) ;
2429+ importBtn ?. addEventListener ( 'click' , ( ) => fileInput ?. click ( ) ) ;
2430+ fileInput ?. addEventListener ( 'change' , ( e ) => this . importSettings ( e , modal ) ) ;
2431+
23512432 // Template and Category action buttons
23522433 modal . addEventListener ( 'click' , ( e ) => {
23532434 const actionBtn = e . target . closest ( '.template-action-btn' ) ;
@@ -3443,6 +3524,177 @@ class PowerToolsUI {
34433524 }
34443525 }
34453526
3527+ exportSettings ( ) {
3528+ try {
3529+ console . log ( '[PowerTools] Starting settings export...' ) ;
3530+
3531+ // Get current configuration
3532+ const config = this . config . load ( ) ;
3533+
3534+ // Create export data with complete configuration
3535+ const exportData = {
3536+ powerToolsExport : true ,
3537+ version : "1.5.1" ,
3538+ exportDate : new Date ( ) . toISOString ( ) ,
3539+ data : {
3540+ templates : config . templates ,
3541+ categories : config . categories ,
3542+ preferences : config . preferences ,
3543+ factoryCategories : JSON . parse ( localStorage . getItem ( 'dictator.powerTools.factoryCategories' ) || '{}' ) ,
3544+ customCategories : JSON . parse ( localStorage . getItem ( 'dictator.powerTools.customCategories' ) || '[]' )
3545+ }
3546+ } ;
3547+
3548+ // Create JSON string
3549+ const jsonString = JSON . stringify ( exportData , null , 2 ) ;
3550+
3551+ // Create downloadable file
3552+ const blob = new Blob ( [ jsonString ] , { type : 'application/json' } ) ;
3553+ const url = URL . createObjectURL ( blob ) ;
3554+
3555+ // Create download link
3556+ const downloadLink = document . createElement ( 'a' ) ;
3557+ downloadLink . href = url ;
3558+ downloadLink . download = `power-tools-settings-${ new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] } .json` ;
3559+ downloadLink . style . display = 'none' ;
3560+
3561+ // Trigger download
3562+ document . body . appendChild ( downloadLink ) ;
3563+ downloadLink . click ( ) ;
3564+ document . body . removeChild ( downloadLink ) ;
3565+
3566+ // Clean up
3567+ URL . revokeObjectURL ( url ) ;
3568+
3569+ console . log ( '[PowerTools] Settings exported successfully' ) ;
3570+ alert ( 'Settings exported successfully! Check your downloads folder.' ) ;
3571+
3572+ } catch ( error ) {
3573+ console . error ( '[PowerTools] Failed to export settings:' , error ) ;
3574+ alert ( 'Failed to export settings: ' + error . message ) ;
3575+ }
3576+ }
3577+
3578+ importSettings ( event , modal ) {
3579+ const file = event . target . files [ 0 ] ;
3580+ if ( ! file ) return ;
3581+
3582+ // Reset file input
3583+ event . target . value = '' ;
3584+
3585+ const reader = new FileReader ( ) ;
3586+
3587+ reader . onload = ( e ) => {
3588+ try {
3589+ console . log ( '[PowerTools] Starting settings import...' ) ;
3590+
3591+ const importData = JSON . parse ( e . target . result ) ;
3592+
3593+ // Validate import data
3594+ if ( ! importData . powerToolsExport || ! importData . data ) {
3595+ throw new Error ( 'Invalid Power Tools export file format' ) ;
3596+ }
3597+
3598+ console . log ( '[PowerTools] Import data validated, version:' , importData . version ) ;
3599+
3600+ // Confirm import
3601+ const confirmMessage = `Import Power Tools settings?\n\n` +
3602+ `Export Date: ${ new Date ( importData . exportDate ) . toLocaleString ( ) } \n` +
3603+ `Version: ${ importData . version } \n` +
3604+ `Templates: ${ Object . keys ( importData . data . templates || { } ) . length } \n` +
3605+ `Categories: ${ Object . keys ( importData . data . categories || { } ) . length } \n\n` +
3606+ `This will replace all current settings!` ;
3607+
3608+ if ( ! confirm ( confirmMessage ) ) {
3609+ console . log ( '[PowerTools] Import cancelled by user' ) ;
3610+ return ;
3611+ }
3612+
3613+ // Apply imported settings
3614+ const data = importData . data ;
3615+
3616+ // Save templates (separate factory and custom)
3617+ if ( data . templates ) {
3618+ const factoryTemplates = { } ;
3619+ const customTemplates = [ ] ;
3620+
3621+ Object . values ( data . templates ) . forEach ( template => {
3622+ if ( template . isFactory ) {
3623+ factoryTemplates [ template . id ] = template ;
3624+ } else {
3625+ customTemplates . push ( template ) ;
3626+ }
3627+ } ) ;
3628+
3629+ // Save factory templates
3630+ if ( Object . keys ( factoryTemplates ) . length > 0 ) {
3631+ localStorage . setItem ( 'dictator.powerTools.factoryTemplates' , JSON . stringify ( factoryTemplates ) ) ;
3632+ console . log ( '[PowerTools] Imported' , Object . keys ( factoryTemplates ) . length , 'factory templates' ) ;
3633+ }
3634+
3635+ // Save custom templates
3636+ if ( customTemplates . length > 0 ) {
3637+ localStorage . setItem ( 'dictator.powerTools.customTemplates' , JSON . stringify ( customTemplates ) ) ;
3638+ console . log ( '[PowerTools] Imported' , customTemplates . length , 'custom templates' ) ;
3639+ }
3640+
3641+ console . log ( '[PowerTools] Total templates imported:' , Object . keys ( data . templates ) . length ) ;
3642+ }
3643+
3644+ // Save factory categories
3645+ if ( data . factoryCategories ) {
3646+ localStorage . setItem ( 'dictator.powerTools.factoryCategories' , JSON . stringify ( data . factoryCategories ) ) ;
3647+ console . log ( '[PowerTools] Imported factory categories' ) ;
3648+ }
3649+
3650+ // Save custom categories
3651+ if ( data . customCategories ) {
3652+ localStorage . setItem ( 'dictator.powerTools.customCategories' , JSON . stringify ( data . customCategories ) ) ;
3653+ console . log ( '[PowerTools] Imported custom categories' ) ;
3654+ }
3655+
3656+ // Save preferences
3657+ if ( data . preferences ) {
3658+ Object . keys ( data . preferences ) . forEach ( key => {
3659+ localStorage . setItem ( `dictator.powerTools.${ key } ` , JSON . stringify ( data . preferences [ key ] ) ) ;
3660+ } ) ;
3661+ console . log ( '[PowerTools] Imported preferences' ) ;
3662+ }
3663+
3664+ // Refresh the UI
3665+ const config = this . config . load ( ) ;
3666+ this . populateTemplatesList ( config . templates ) ;
3667+ this . populateCategoriesList ( config . categories ) ;
3668+ this . registerHotkeys ( ) ;
3669+
3670+ // Update preferences in the modal
3671+ const showHotkeysCheckbox = modal . querySelector ( '#show-hotkeys' ) ;
3672+ const groupByCategoryCheckbox = modal . querySelector ( '#group-by-category' ) ;
3673+ const compactModeCheckbox = modal . querySelector ( '#compact-mode' ) ;
3674+ const autoFocusInputCheckbox = modal . querySelector ( '#auto-focus-input' ) ;
3675+
3676+ if ( showHotkeysCheckbox ) showHotkeysCheckbox . checked = config . preferences . showHotkeys ;
3677+ if ( groupByCategoryCheckbox ) groupByCategoryCheckbox . checked = config . preferences . groupByCategory ;
3678+ if ( compactModeCheckbox ) compactModeCheckbox . checked = config . preferences . compactMode ;
3679+ if ( autoFocusInputCheckbox ) autoFocusInputCheckbox . checked = config . preferences . autoFocusInput ;
3680+
3681+ console . log ( '[PowerTools] Settings imported successfully' ) ;
3682+ alert ( 'Settings imported successfully! All templates, categories, and preferences have been restored.' ) ;
3683+
3684+ } catch ( error ) {
3685+ console . error ( '[PowerTools] Failed to import settings:' , error ) ;
3686+ alert ( 'Failed to import settings: ' + error . message ) ;
3687+ }
3688+ } ;
3689+
3690+ reader . onerror = ( ) => {
3691+ console . error ( '[PowerTools] Failed to read import file' ) ;
3692+ alert ( 'Failed to read the selected file. Please try again.' ) ;
3693+ } ;
3694+
3695+ reader . readAsText ( file ) ;
3696+ }
3697+
34463698}
34473699
34483700// Initialize Power Tools
@@ -3477,7 +3729,7 @@ window.PowerTools = {
34773729 }
34783730} ;
34793731
3480- console . log ( '[PowerTools] Power Tools system loaded - v1.4.2 with AutoSend, Drag-to-Reorder, Category Manager, and Cross-Category Dragging features (Category Order & Context Menu Fixes )' ) ;
3732+ console . log ( '[PowerTools] Power Tools system loaded - v1.5.1 with AutoSend, Drag-to-Reorder, Category Manager, Cross-Category Dragging, and Import/Export features (Import Bug Fix )' ) ;
34813733
34823734// Auto-dismiss Cursor corruption notification (same as dictator.js)
34833735setTimeout ( ( ) => {
@@ -3534,6 +3786,6 @@ setTimeout(() => {
35343786 if ( ! findAndDismissCorruptionNotification ( ) ) {
35353787 console . log ( '[PowerTools] No corruption notification found to dismiss.' ) ;
35363788 }
3537- } , 3000 ) ;
3789+ } , 5000 ) ;
35383790 }
3539- } , 2000 ) ;
3791+ } , 3000 ) ;
0 commit comments