main
vue 131 lines 3.84 KB
Raw
1 <template>
2 <n-form :model="formData" :rules label-placement="left" label-width="160px">
3 <n-form-item label="Snapshot">
4 <n-input :value="snapshot?.snapshot" disabled />
5 </n-form-item>
6
7 <n-form-item label="Indices in Snapshot">
8 <n-tag v-for="index in snapshot?.indices.slice(0, 5)" :key="index" size="small" class="mr-1 mb-1">
9 {{ index }}
10 </n-tag>
11 <n-tag v-if="(snapshot?.indices.length || 0) > 5" size="small">
12 +{{ (snapshot?.indices.length || 0) - 5 }} more
13 </n-tag>
14 </n-form-item>
15
16 <n-form-item label="Indices to Restore" path="indices">
17 <n-input
18 v-model:value="indicesInput"
19 placeholder="Leave empty to restore all indices, or enter specific indices (comma-separated)"
20 type="textarea"
21 :rows="2"
22 />
23 </n-form-item>
24
25 <n-form-item label="Rename Pattern" path="rename_pattern">
26 <n-input v-model:value="formData.rename_pattern" placeholder="e.g., (.+)" />
27 </n-form-item>
28
29 <n-form-item label="Rename Replacement" path="rename_replacement">
30 <n-input v-model:value="formData.rename_replacement" placeholder="e.g., restored_$1" />
31 </n-form-item>
32
33 <n-form-item label="Include Global State" path="include_global_state">
34 <n-switch v-model:value="formData.include_global_state" />
35 </n-form-item>
36
37 <n-form-item label="Include Aliases" path="include_aliases">
38 <n-switch v-model:value="formData.include_aliases" />
39 </n-form-item>
40
41 <n-form-item label="Ignore Unavailable" path="ignore_unavailable">
42 <n-switch v-model:value="formData.ignore_unavailable" />
43 </n-form-item>
44
45 <n-alert type="warning" class="mb-4">
46 <strong>Note:</strong>
47 If an index with the same name already exists, use the rename pattern to restore under a different name.
48 Example: Pattern
49 <code>(.+)</code>
50 with replacement
51 <code>restored_$1</code>
52 </n-alert>
53
54 <div class="mt-4 flex justify-end gap-2">
55 <n-button @click="$emit('cancel')">Cancel</n-button>
56 <n-button type="primary" :loading @click="handleSubmit">Restore Snapshot</n-button>
57 </div>
58 </n-form>
59 </template>
60
61 <script setup lang="ts">
62 // TODO-FE: refactor
63 import type { FormRules } from "naive-ui"
64 import type { RestoreSnapshotRequest, SnapshotInfo } from "@/types/snapshots.d"
65 import { NAlert, NButton, NForm, NFormItem, NInput, NSwitch, NTag, useMessage } from "naive-ui"
66 import { ref } from "vue"
67 import Api from "@/api"
68
69 const props = defineProps<{
70 repository: string | null
71 snapshot: SnapshotInfo | null
72 }>()
73
74 const emit = defineEmits<{
75 (e: "success"): void
76 (e: "cancel"): void
77 }>()
78
79 const message = useMessage()
80 const loading = ref(false)
81 const indicesInput = ref("")
82
83 const formData = ref({
84 rename_pattern: "(.+)",
85 rename_replacement: "restored_$1",
86 include_global_state: false,
87 include_aliases: true,
88 ignore_unavailable: true,
89 partial: false
90 })
91
92 const rules: FormRules = {}
93
94 async function handleSubmit() {
95 if (!props.repository || !props.snapshot) {
96 message.error("Repository and snapshot are required")
97 return
98 }
99
100 loading.value = true
101 try {
102 const indices = indicesInput.value
103 .split(",")
104 .map(s => s.trim())
105 .filter(s => s.length > 0)
106
107 const request: RestoreSnapshotRequest = {
108 repository: props.repository,
109 snapshot: props.snapshot.snapshot,
110 indices: indices.length > 0 ? indices : undefined,
111 rename_pattern: formData.value.rename_pattern || undefined,
112 rename_replacement: formData.value.rename_replacement || undefined,
113 include_global_state: formData.value.include_global_state,
114 include_aliases: formData.value.include_aliases,
115 ignore_unavailable: formData.value.ignore_unavailable,
116 partial: formData.value.partial
117 }
118
119 const response = await Api.snapshots.restoreSnapshot(request)
120 if (response.data.success) {
121 emit("success")
122 } else {
123 message.error(response.data.message)
124 }
125 } catch (error: any) {
126 message.error(error.message || "Failed to restore snapshot")
127 } finally {
128 loading.value = false
129 }
130 }
131 </script>