main
vue 137 lines 3.5 KB
Raw
1 <template>
2 <n-form ref="formRef" :model="formValue" :rules label-placement="top">
3 <n-form-item label="Customer" path="customer_code">
4 <n-select
5 v-model:value="formValue.customer_code"
6 :options="customers"
7 placeholder="Select customer"
8 filterable
9 clearable
10 />
11 </n-form-item>
12
13 <n-form-item label="Report Name (Optional)" path="report_name">
14 <n-input
15 v-model:value="formValue.report_name"
16 placeholder="Leave empty for auto-generated name"
17 clearable
18 />
19 </n-form-item>
20
21 <n-divider>Filters (Optional)</n-divider>
22
23 <n-form-item label="Agent Name" path="agent_name">
24 <n-input v-model:value="formValue.agent_name" placeholder="Filter by specific agent" clearable />
25 </n-form-item>
26
27 <n-form-item label="Policy ID" path="policy_id">
28 <n-input v-model:value="formValue.policy_id" placeholder="Filter by specific policy ID" clearable />
29 </n-form-item>
30
31 <n-form-item label="Minimum Score" path="min_score">
32 <n-input-number
33 v-model:value="formValue.min_score"
34 :min="0"
35 :max="100"
36 placeholder="Filter by minimum compliance score"
37 clearable
38 class="w-full"
39 />
40 </n-form-item>
41
42 <n-form-item label="Maximum Score" path="max_score">
43 <n-input-number
44 v-model:value="formValue.max_score"
45 :min="0"
46 :max="100"
47 placeholder="Filter by maximum compliance score"
48 clearable
49 class="w-full"
50 />
51 </n-form-item>
52
53 <n-space justify="end" class="mt-4">
54 <n-button @click="$emit('cancel')">Cancel</n-button>
55 <n-button type="primary" :loading @click="handleGenerate">
56 <template #icon>
57 <Icon :name="GenerateIcon" />
58 </template>
59 Generate Report
60 </n-button>
61 </n-space>
62 </n-form>
63 </template>
64
65 <script setup lang="ts">
66 // TODO-FE: refactor
67 import type { FormInst, FormRules } from "naive-ui"
68 import type { SCAReportGenerateRequest } from "@/types/sca.d"
69 import { NButton, NDivider, NForm, NFormItem, NInput, NInputNumber, NSelect, NSpace } from "naive-ui"
70 import { ref } from "vue"
71 import Icon from "@/components/common/Icon.vue"
72
73 defineProps<Props>()
74
75 const emit = defineEmits<{
76 generate: [request: SCAReportGenerateRequest]
77 cancel: []
78 }>()
79
80 const GenerateIcon = "carbon:document-add"
81
82 interface Props {
83 customers: Array<{ label: string; value: string }>
84 loading?: boolean
85 }
86
87 const formRef = ref<FormInst | null>(null)
88 const formValue = ref<SCAReportGenerateRequest>({
89 customer_code: "",
90 report_name: undefined,
91 agent_name: undefined,
92 policy_id: undefined,
93 min_score: undefined,
94 max_score: undefined
95 })
96
97 const rules: FormRules = {
98 customer_code: [
99 {
100 required: true,
101 message: "Please select a customer",
102 trigger: ["blur", "change"]
103 }
104 ]
105 }
106
107 async function handleGenerate() {
108 try {
109 await formRef.value?.validate()
110
111 // Clean up empty optional fields
112 const request: SCAReportGenerateRequest = {
113 customer_code: formValue.value.customer_code
114 }
115
116 if (formValue.value.report_name) request.report_name = formValue.value.report_name
117 if (formValue.value.agent_name) request.agent_name = formValue.value.agent_name
118 if (formValue.value.policy_id) request.policy_id = formValue.value.policy_id
119 if (formValue.value.min_score !== undefined && formValue.value.min_score !== null) {
120 request.min_score = formValue.value.min_score
121 }
122 if (formValue.value.max_score !== undefined && formValue.value.max_score !== null) {
123 request.max_score = formValue.value.max_score
124 }
125
126 emit("generate", request)
127 } catch (error) {
128 console.error("Form validation failed:", error)
129 }
130 }
131 </script>
132
133 <style scoped>
134 .w-full {
135 width: 100%;
136 }
137 </style>