| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <v-container fluid> | 
					
						
							|  |  |  |     <section> | 
					
						
							|  |  |  |       <!-- Delete Dialog --> | 
					
						
							|  |  |  |       <BaseDialog | 
					
						
							| 
									
										
										
										
											2021-11-25 14:17:02 -09:00
										 |  |  |         v-model="deleteDialog" | 
					
						
							| 
									
										
										
										
											2022-08-14 11:06:35 -08:00
										 |  |  |         :title="$tc('settings.backup.delete-backup')" | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |         color="error" | 
					
						
							|  |  |  |         :icon="$globals.icons.alertCircle" | 
					
						
							|  |  |  |         @confirm="deleteBackup()" | 
					
						
							|  |  |  |       > | 
					
						
							|  |  |  |         <v-card-text> | 
					
						
							|  |  |  |           {{ $t("general.confirm-delete-generic") }} | 
					
						
							|  |  |  |         </v-card-text> | 
					
						
							|  |  |  |       </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       <!-- Import Dialog --> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |       <BaseDialog v-model="importDialog" color="error" :title="$t('settings.backup.backup-restore')" :icon="$globals.icons.database"> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |         <v-divider></v-divider> | 
					
						
							|  |  |  |         <v-card-text> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |           <i18n path="settings.backup.back-restore-description"> | 
					
						
							|  |  |  |             <template #cannot-be-undone> | 
					
						
							|  |  |  |               <b> {{ $t('settings.backup.cannot-be-undone') }} </b> | 
					
						
							|  |  |  |             </template> | 
					
						
							|  |  |  |           </i18n> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 11:53:48 -08:00
										 |  |  |           <p class="mt-3"> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |             <i18n path="settings.backup.postgresql-note"> | 
					
						
							|  |  |  |               <template #backup-restore-process> | 
					
						
							|  |  |  |                 <a href="https://nightly.mealie.io/documentation/getting-started/usage/backups-and-restoring/" >{{ $t('settings.backup.backup-restore-process-in-the-documentation') }}</a > | 
					
						
							|  |  |  |               </template> | 
					
						
							|  |  |  |             </i18n> | 
					
						
							|  |  |  |             {{ $t('') }} | 
					
						
							| 
									
										
										
										
											2022-08-20 11:53:48 -08:00
										 |  |  |           </p> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |           <v-checkbox | 
					
						
							|  |  |  |             v-model="confirmImport" | 
					
						
							|  |  |  |             class="checkbox-top" | 
					
						
							|  |  |  |             color="error" | 
					
						
							|  |  |  |             hide-details | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |             :label="$t('settings.backup.irreversible-acknowledgment')" | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |           ></v-checkbox> | 
					
						
							|  |  |  |         </v-card-text> | 
					
						
							|  |  |  |         <v-card-actions class="justify-center pt-0"> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |           <BaseButton delete :disabled="!confirmImport || runningRestore" @click="restoreBackup(selected)"> | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |             <template #icon> {{ $globals.icons.database }} </template> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |             {{ $t('settings.backup.restore-backup') }} | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |           </BaseButton> | 
					
						
							|  |  |  |         </v-card-actions> | 
					
						
							|  |  |  |         <p class="caption pb-0 mb-1 text-center"> | 
					
						
							| 
									
										
										
										
											2022-08-14 11:06:35 -08:00
										 |  |  |           {{ selected }} | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |         </p> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |         <v-progress-linear v-if="runningRestore" indeterminate></v-progress-linear> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |       </BaseDialog> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       <section> | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |         <BaseCardSectionTitle :title="$tc('settings.backup-and-exports')"> | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |           <v-card-text class="py-0 px-1"> | 
					
						
							| 
									
										
										
										
											2023-10-07 14:23:26 -05:00
										 |  |  |           <i18n path="settings.backup.experimental-description" /> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |           </v-card-text> | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |         </BaseCardSectionTitle> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |         <v-toolbar color="background" flat class="justify-between"> | 
					
						
							|  |  |  |         <BaseButton class="mr-2" @click="createBackup"> {{ $t("settings.backup.create-heading") }} </BaseButton> | 
					
						
							|  |  |  |         <AppButtonUpload | 
					
						
							|  |  |  |                 :text-btn="false" | 
					
						
							|  |  |  |                 url="/api/admin/backups/upload" | 
					
						
							|  |  |  |                 accept=".zip" | 
					
						
							|  |  |  |                 color="info" | 
					
						
							|  |  |  |                 @uploaded="refreshBackups()" | 
					
						
							|  |  |  |               /> | 
					
						
							|  |  |  |         </v-toolbar> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-04 14:18:46 -09:00
										 |  |  |         <v-data-table | 
					
						
							|  |  |  |           :headers="headers" | 
					
						
							|  |  |  |           :items="backups.imports || []" | 
					
						
							|  |  |  |           class="elevation-0" | 
					
						
							|  |  |  |           hide-default-footer | 
					
						
							|  |  |  |           disable-pagination | 
					
						
							|  |  |  |           :search="search" | 
					
						
							|  |  |  |           @click:row="setSelected" | 
					
						
							|  |  |  |         > | 
					
						
							|  |  |  |           <template #item.date="{ item }"> | 
					
						
							|  |  |  |             {{ $d(Date.parse(item.date), "medium") }} | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |           <template #item.actions="{ item }"> | 
					
						
							|  |  |  |             <v-btn | 
					
						
							|  |  |  |               icon | 
					
						
							|  |  |  |               class="mx-1" | 
					
						
							|  |  |  |               color="error" | 
					
						
							|  |  |  |               @click.stop=" | 
					
						
							|  |  |  |                 deleteDialog = true; | 
					
						
							|  |  |  |                 deleteTarget = item.name; | 
					
						
							|  |  |  |               " | 
					
						
							|  |  |  |             > | 
					
						
							|  |  |  |               <v-icon> {{ $globals.icons.delete }} </v-icon> | 
					
						
							|  |  |  |             </v-btn> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |             <BaseButton small download :download-url="backupsFileNameDownload(item.name)" class="mx-1" @click.stop="() => {}"/> | 
					
						
							|  |  |  |             <BaseButton small @click.stop="setSelected(item); importDialog = true"> | 
					
						
							|  |  |  |               <template #icon> {{ $globals.icons.backupRestore }}</template> | 
					
						
							|  |  |  |               {{ $t("settings.backup.backup-restore") }} | 
					
						
							|  |  |  |           </BaseButton> | 
					
						
							| 
									
										
										
										
											2021-12-04 14:18:46 -09:00
										 |  |  |           </template> | 
					
						
							|  |  |  |         </v-data-table> | 
					
						
							|  |  |  |         <v-divider></v-divider> | 
					
						
							|  |  |  |         <div class="d-flex justify-end mt-6"> | 
					
						
							|  |  |  |           <div> | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-04 14:18:46 -09:00
										 |  |  |           </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </section> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |     </section> | 
					
						
							| 
									
										
										
										
											2023-10-07 21:36:47 +02:00
										 |  |  |     <v-container class="mt-4 d-flex justify-center text-center"> | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |       <nuxt-link :to="`/group/migrations`"> {{ $t('recipe.looking-for-migrations') }} </nuxt-link> | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |     </v-container> | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |   </v-container> | 
					
						
							|  |  |  | </template> | 
					
						
							| 
									
										
										
										
											2021-08-21 11:00:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | <script lang="ts"> | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  | import { computed, defineComponent, reactive, ref, toRefs, useContext, onMounted, useRoute } from "@nuxtjs/composition-api"; | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  | import { useAdminApi } from "~/composables/api"; | 
					
						
							| 
									
										
										
										
											2022-10-22 11:51:07 -08:00
										 |  |  | import { AllBackups } from "~/lib/api/types/admin"; | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  | import { alert } from "~/composables/use-toast"; | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default defineComponent({ | 
					
						
							|  |  |  |   layout: "admin", | 
					
						
							|  |  |  |   setup() { | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |     const { i18n, $auth } = useContext(); | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |     const route = useRoute(); | 
					
						
							|  |  |  |     const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const adminApi = useAdminApi(); | 
					
						
							|  |  |  |     const selected = ref(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const backups = ref<AllBackups>({ | 
					
						
							|  |  |  |       imports: [], | 
					
						
							|  |  |  |       templates: [], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function refreshBackups() { | 
					
						
							|  |  |  |       const { data } = await adminApi.backups.getAll(); | 
					
						
							|  |  |  |       if (data) { | 
					
						
							|  |  |  |         backups.value = data; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function createBackup() { | 
					
						
							|  |  |  |       const { data } = await adminApi.backups.create(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-19 16:10:31 +01:00
										 |  |  |       if (data?.error === false) { | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |         refreshBackups(); | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |         alert.success(i18n.tc("settings.backup.backup-created")); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         alert.error(i18n.tc("settings.backup.error-creating-backup-see-log-file")); | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async function restoreBackup(fileName: string) { | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |       state.runningRestore = true; | 
					
						
							| 
									
										
										
										
											2022-08-14 11:06:35 -08:00
										 |  |  |       const { error } = await adminApi.backups.restore(fileName); | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-14 11:06:35 -08:00
										 |  |  |       if (error) { | 
					
						
							|  |  |  |         console.log(error); | 
					
						
							|  |  |  |         state.importDialog = false; | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         alert.success(i18n.tc("settings.backup.restore-success")); | 
					
						
							|  |  |  |         $auth.logout(); | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const deleteTarget = ref(""); | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |     async function deleteBackup() { | 
					
						
							|  |  |  |       const { data } = await adminApi.backups.delete(deleteTarget.value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!data?.error) { | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |         alert.success(i18n.tc("settings.backup.backup-deleted")); | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |         refreshBackups(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const state = reactive({ | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       confirmImport: false, | 
					
						
							| 
									
										
										
										
											2021-11-25 14:17:02 -09:00
										 |  |  |       deleteDialog: false, | 
					
						
							|  |  |  |       createDialog: false, | 
					
						
							|  |  |  |       importDialog: false, | 
					
						
							| 
									
										
										
										
											2023-11-24 10:44:42 +01:00
										 |  |  |       runningRestore: false, | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |       search: "", | 
					
						
							|  |  |  |       headers: [ | 
					
						
							|  |  |  |         { text: i18n.t("general.name"), value: "name" }, | 
					
						
							|  |  |  |         { text: i18n.t("general.created"), value: "date" }, | 
					
						
							| 
									
										
										
										
											2023-03-21 20:45:27 +01:00
										 |  |  |         { text: i18n.t("export.size"), value: "size" }, | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |         { text: "", value: "actions", align: "right" }, | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function setSelected(data: { name: string; date: string }) { | 
					
						
							|  |  |  |       if (selected.value === null || selected.value === undefined) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       selected.value = data.name; | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |     const backupsFileNameDownload = (fileName: string) => `api/admin/backups/${fileName}`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     onMounted(refreshBackups); | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2023-11-05 19:07:02 -06:00
										 |  |  |       groupSlug, | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       restoreBackup, | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |       selected, | 
					
						
							|  |  |  |       ...toRefs(state), | 
					
						
							|  |  |  |       backups, | 
					
						
							|  |  |  |       createBackup, | 
					
						
							|  |  |  |       deleteBackup, | 
					
						
							|  |  |  |       deleteTarget, | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  |       setSelected, | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  |       refreshBackups, | 
					
						
							|  |  |  |       backupsFileNameDownload, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-10-07 09:39:47 -08:00
										 |  |  |   head() { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       title: this.$t("sidebar.backups") as string, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2021-08-21 00:46:43 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							| 
									
										
										
										
											2022-03-13 15:42:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | <style> | 
					
						
							|  |  |  | .v-input--selection-controls__input { | 
					
						
							|  |  |  |   margin-bottom: auto; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | </style> |