@ -1,3 +1,17 @@
/ * *
* Data Export Section Component
*
* Provides UI and functionality for exporting user data and backing up identifier seeds .
* Includes buttons for seed backup and database export , with platform - specific download instructions .
*
* @ component
* @ displayName DataExportSection
* @ example
* ` ` ` vue
* < DataExportSection :active-did ="currentDid" / >
* ` ` `
* /
< template >
< template >
< div
< div
id = "sectionDataExport"
id = "sectionDataExport"
@ -28,17 +42,17 @@
>
>
If no download happened yet , click again here to download now .
If no download happened yet , click again here to download now .
< / a >
< / a >
< div class = "mt-4" >
< div class = "mt-4" v-if ="showPlatformInstructions" >
< p >
< p >
After the download , you can save the file in your preferred storage
After the download , you can save the file in your preferred storage
location .
location .
< / p >
< / p >
< ul >
< ul >
< li class = "list-disc list-outside ml-4" >
< li v-if ="platformService.isCapacitor() && isIOS" class="list-disc list-outside ml-4" >
On iOS : Choose "More..." and select a place in iCloud , or go "Back"
On iOS : Choose "More..." and select a place in iCloud , or go "Back"
and save to another location .
and save to another location .
< / li >
< / li >
< li class = "list-disc list-outside ml-4" >
< li v-if ="platformService.isCapacitor() && !isIOS" class="list-disc list-outside ml-4" >
On Android : Choose "Open" and then share
On Android : Choose "Open" and then share
< font -awesome icon = "share-nodes" class = "fa-fw" / >
< font -awesome icon = "share-nodes" class = "fa-fw" / >
to your prefered place .
to your prefered place .
@ -53,38 +67,106 @@ import { Component, Prop, Vue } from "vue-facing-decorator";
import { NotificationIface } from "../constants/app" ;
import { NotificationIface } from "../constants/app" ;
import { db } from "../db/index" ;
import { db } from "../db/index" ;
import { logger } from "../utils/logger" ;
import { logger } from "../utils/logger" ;
import { PlatformServiceFactory } from "../services/PlatformServiceFactory" ;
import { PlatformService } from "../services/PlatformService" ;
/ * *
* @ vue - component
* Data Export Section Component
* Handles database export and seed backup functionality with platform - specific behavior
* /
@ Component
@ Component
export default class DataExportSection extends Vue {
export default class DataExportSection extends Vue {
/ * *
* Notification function injected by Vue
* Used to show success / error messages to the user
* /
$notify ! : ( notification : NotificationIface , timeout ? : number ) => void ;
$notify ! : ( notification : NotificationIface , timeout ? : number ) => void ;
/ * *
* Active DID ( Decentralized Identifier ) of the user
* Controls visibility of seed backup option
* @ required
* /
@ Prop ( { required : true } ) readonly activeDid ! : string ;
@ Prop ( { required : true } ) readonly activeDid ! : string ;
/ * *
* URL for the database export download
* Created and revoked dynamically during export process
* Only used in web platform
* /
downloadUrl = "" ;
downloadUrl = "" ;
/ * *
* Platform service instance for platform - specific operations
* /
private platformService : PlatformService = PlatformServiceFactory . getInstance ( ) ;
/ * *
* Whether the current platform is iOS
* /
private get isIOS ( ) : boolean {
return /iPad|iPhone|iPod/ . test ( navigator . userAgent ) ;
}
/ * *
* Whether to show platform - specific instructions
* /
private get showPlatformInstructions ( ) : boolean {
return this . platformService . isCapacitor ( ) ;
}
/ * *
* Lifecycle hook to clean up resources
* Revokes object URL when component is unmounted ( web platform only )
* /
beforeUnmount ( ) {
beforeUnmount ( ) {
if ( this . downloadUrl ) {
if ( this . downloadUrl && this . platformService . isWeb ( ) ) {
URL . revokeObjectURL ( this . downloadUrl ) ;
URL . revokeObjectURL ( this . downloadUrl ) ;
}
}
}
}
/ * *
* Exports the database to a JSON file
* Uses platform - specific methods for saving the exported data
* Shows success / error notifications to user
*
* @ throws { Error } If export fails
* @ emits { Notification } Success or error notification
* /
public async exportDatabase ( ) {
public async exportDatabase ( ) {
try {
try {
const blob = await db . export ( { prettyJson : true } ) ;
const blob = await db . export ( { prettyJson : true } ) ;
this . downloadUrl = URL . createObjectURL ( blob ) ;
const fileName = ` ${ db . name } -backup.json ` ;
const downloadAnchor = this . $refs . downloadLink as HTMLAnchorElement ;
downloadAnchor . href = this . downloadUrl ;
if ( this . platformService . isWeb ( ) ) {
downloadAnchor . download = ` ${ db . name } -backup.json ` ;
/ / W e b p l a t f o r m : U s e d o w n l o a d l i n k
downloadAnchor . click ( ) ;
this . downloadUrl = URL . createObjectURL ( blob ) ;
const downloadAnchor = this . $refs . downloadLink as HTMLAnchorElement ;
downloadAnchor . href = this . downloadUrl ;
downloadAnchor . download = fileName ;
downloadAnchor . click ( ) ;
setTimeout ( ( ) => URL . revokeObjectURL ( this . downloadUrl ) , 1000 ) ;
} else if ( this . platformService . isCapacitor ( ) ) {
/ / C a p a c i t o r p l a t f o r m : W r i t e t o a p p d i r e c t o r y
const content = await blob . text ( ) ;
await this . platformService . writeFile ( fileName , content ) ;
} else {
/ / O t h e r p l a t f o r m s : U s e p l a t f o r m s e r v i c e
await this . platformService . writeFile ( fileName , await blob . text ( ) ) ;
}
this . $notify (
this . $notify (
{
{
group : "alert" ,
group : "alert" ,
type : "success" ,
type : "success" ,
title : "Download Started" ,
title : "Export Successful" ,
text : "See your downloads directory for the backup. It is in the Dexie format." ,
text : this . platformService . isWeb ( )
? "See your downloads directory for the backup. It is in the Dexie format."
: "The backup has been saved to your device." ,
} ,
} ,
- 1 ,
- 1 ,
) ;
) ;
setTimeout ( ( ) => URL . revokeObjectURL ( this . downloadUrl ) , 1000 ) ;
} catch ( error ) {
} catch ( error ) {
logger . error ( "Export Error:" , error ) ;
logger . error ( "Export Error:" , error ) ;
this . $notify (
this . $notify (
@ -99,15 +181,23 @@ export default class DataExportSection extends Vue {
}
}
}
}
/ * *
* Computes class names for the initial download button
* @ returns Object with 'hidden' class when download is in progress ( web platform only )
* /
public computedStartDownloadLinkClassNames ( ) {
public computedStartDownloadLinkClassNames ( ) {
return {
return {
hidden : this . downloadUrl ,
hidden : this . downloadUrl && this . platformService . isWeb ( ) ,
} ;
} ;
}
}
/ * *
* Computes class names for the secondary download link
* @ returns Object with 'hidden' class when no download is available or not on web platform
* /
public computedDownloadLinkClassNames ( ) {
public computedDownloadLinkClassNames ( ) {
return {
return {
hidden : ! this . downloadUrl ,
hidden : ! this . downloadUrl || ! this . platformService . isWeb ( ) ,
} ;
} ;
}
}
}
}