8686 <p class =" description" >{{ t('removeAllData.description') }}</p >
8787 <input type =" button" :value =" t('remove.message')" @click =" removeAll()" />
8888 </div >
89+ <div class =" settings-item" >
90+ <label class =" setting-header d-inline-block" >{{ t('backupAndRestore.message') }}</label >
91+ <p class =" description" >{{ t('backupAndRestore.description') }}</p >
92+ <input type =" button" :value =" t('backup.message')" @click =" backup()" />
93+ <input
94+ type =" file"
95+ ref =" restoreFile"
96+ style =" display : none "
97+ @change =" restoreFileUpload()"
98+ accept =" application/json"
99+ />
100+ <input type =" button" class =" ml-10" :value =" t('restore.message')" @click =" restore()" />
101+ </div >
89102 <div id =" removeAllConfirmModal" class =" modal" v-if =" needToConfirmDeleteAllData" >
90103 <div class =" modal-content" >
91104 <p class =" text-center" >{{ t('removeAllDataConfirm.message') }}</p >
@@ -121,10 +134,12 @@ import {
121134 VIEW_TIME_IN_BADGE_DEFAULT ,
122135 InactivityInterval ,
123136} from ' ../storage/storage-params' ;
124- import { ranges , ThisWeekRange } from ' ../utils/date' ;
137+ import { ranges , ThisWeekRange , todayLocalDate } from ' ../utils/date' ;
125138import { useImportToCsv } from ' ../compositions/toCsv' ;
126139import { FileType , useFile } from ' ../compositions/loadFile' ;
127140import { removeAllData } from ' ../compositions/remove-all-data' ;
141+ import { injectTabsRepository } from ' ../repository/inject-tabs-repository' ;
142+ import { restoreData } from ' ../compositions/restoreData' ;
128143
129144const { t } = useI18n ();
130145
@@ -141,6 +156,8 @@ const presetRanges = ranges();
141156
142157const needToConfirmDeleteAllData = ref <boolean >();
143158
159+ const restoreFile = ref <any >();
160+
144161onMounted (async () => {
145162 viewTimeInBadge .value = await settingsStorage .getValue (
146163 StorageParams .VIEW_TIME_IN_BADGE ,
@@ -204,6 +221,45 @@ async function removeAllConfirm() {
204221function cancel() {
205222 needToConfirmDeleteAllData .value = false ;
206223}
224+
225+ async function backup() {
226+ const repo = await injectTabsRepository ();
227+ const tabs = repo .getTabs ();
228+ const json = JSON .stringify (tabs );
229+ useFile (json , FileType .JSON , ` backup-${todayLocalDate ()}.json ` );
230+ }
231+
232+ function restore() {
233+ restoreFile .value .click ();
234+ }
235+
236+ function restoreFileUpload() {
237+ try {
238+ const file = restoreFile .value .files [0 ];
239+ if (file != null && file .type === FileType .JSON ) {
240+ var reader = new FileReader ();
241+ reader .readAsText (file , ' UTF-8' );
242+ reader .onload = async readerEvent => {
243+ if (readerEvent != null ) {
244+ let content = readerEvent .target ?.result ;
245+ if (content != null ) {
246+ await restoreData (content as string );
247+ }
248+ }
249+ };
250+ } else {
251+ notification .notify ({
252+ title: ' Wrong restore file format' ,
253+ type: ' warn' ,
254+ });
255+ }
256+ } catch {
257+ notification .notify ({
258+ title: ' Wrong restore file format' ,
259+ type: ' warn' ,
260+ });
261+ }
262+ }
207263 </script >
208264
209265<style scoped>
0 commit comments