main
vue 130 lines 3.53 KB
Raw
1 <template>
2 <div class="flex flex-col gap-4">
3 <n-form ref="formRef" :model="formData" :rules label-placement="top">
4 <n-form-item label="Check to Exclude" path="check_id">
5 <n-select
6 v-model:value="formData.check_id"
7 placeholder="Select a check"
8 :options="checkOptions"
9 filterable
10 />
11 </n-form-item>
12
13 <n-form-item label="Resource Name (Optional)">
14 <n-input
15 v-model:value="formData.resource_name"
16 placeholder="e.g., specific repository name (leave blank for all)"
17 />
18 </n-form-item>
19
20 <n-form-item label="Reason" path="reason">
21 <n-input
22 v-model:value="formData.reason"
23 type="textarea"
24 placeholder="Why is this check being excluded?"
25 :rows="3"
26 />
27 </n-form-item>
28
29 <n-form-item label="Approved By">
30 <n-input v-model:value="formData.approved_by" placeholder="Name of approver" />
31 </n-form-item>
32
33 <n-form-item label="Expires At">
34 <n-date-picker v-model:value="expiresAtTimestamp" type="datetime" clearable />
35 </n-form-item>
36 </n-form>
37
38 <div class="flex justify-end gap-3">
39 <n-button @click="emit('cancel')">Cancel</n-button>
40 <n-button type="primary" :loading="saving" @click="handleSubmit">Create</n-button>
41 </div>
42 </div>
43 </template>
44
45 <script setup lang="ts">
46 import type { FormInst, FormRules } from "naive-ui"
47 import type { GitHubAuditExclusionCreate } from "@/types/githubAudit.d"
48 import { NButton, NDatePicker, NForm, NFormItem, NInput, NSelect, useMessage } from "naive-ui"
49 import { onBeforeMount, reactive, ref } from "vue"
50 import Api from "@/api"
51 import { useAuthStore } from "@/stores/auth"
52
53 type ExclusionFormData = Omit<GitHubAuditExclusionCreate, "created_by" | "check_id" | "reason"> & {
54 check_id: string | null
55 reason: string | null
56 }
57
58 const props = defineProps<{
59 configId: number
60 }>()
61
62 const emit = defineEmits<{
63 (e: "saved"): void
64 (e: "cancel"): void
65 }>()
66
67 const message = useMessage()
68 const authStore = useAuthStore()
69 const formRef = ref<FormInst | null>(null)
70 const saving = ref(false)
71 const checkOptions = ref<{ label: string; value: string }[]>([])
72 const expiresAtTimestamp = ref<number | null>(null)
73
74 const formData = reactive<ExclusionFormData>({
75 check_id: null,
76 resource_name: null,
77 reason: null,
78 approved_by: null,
79 expires_at: null
80 })
81
82 const rules: FormRules = {
83 check_id: { required: true, message: "Please select a check", trigger: "blur" },
84 reason: { required: true, message: "Please provide a reason", trigger: "blur" }
85 }
86
87 async function handleSubmit() {
88 try {
89 await formRef.value?.validate()
90 } catch {
91 return
92 }
93
94 saving.value = true
95 try {
96 const data: GitHubAuditExclusionCreate = {
97 ...formData,
98 check_id: formData.check_id ?? "",
99 reason: formData.reason ?? "",
100 created_by: authStore.userName,
101 expires_at: expiresAtTimestamp.value ? new Date(expiresAtTimestamp.value).toISOString() : null
102 }
103 await Api.githubAudit.createExclusion(props.configId, data)
104 message.success("Exclusion created successfully")
105 emit("saved")
106
107 formData.check_id = ""
108 formData.resource_name = null
109 formData.reason = ""
110 formData.approved_by = null
111 expiresAtTimestamp.value = null
112 } catch (error: any) {
113 message.error(error.response?.data?.detail || "Failed to create exclusion")
114 } finally {
115 saving.value = false
116 }
117 }
118
119 onBeforeMount(async () => {
120 try {
121 const response = await Api.githubAudit.getAvailableChecks()
122 checkOptions.value = response.data.checks.map(check => ({
123 label: `${check.name} (${check.severity})`,
124 value: check.id
125 }))
126 } catch (error) {
127 console.error("Failed to load available checks:", error)
128 }
129 })
130 </script>