Skip to content

Commit 398eea2

Browse files
committed
enhance: show the form error details of Preference
1 parent b0a3989 commit 398eea2

File tree

8 files changed

+74
-22
lines changed

8 files changed

+74
-22
lines changed

api/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@ func BindAndValid(c *gin.Context, target interface{}) bool {
3838
return false
3939
}
4040

41-
t := reflect.TypeOf(target)
41+
t := reflect.TypeOf(target).Elem()
4242
errorsMap := make(map[string]interface{})
4343
for _, value := range verrs {
4444
var path []string
4545

4646
namespace := strings.Split(value.StructNamespace(), ".")
47-
48-
if t.Name() == "" && len(namespace) > 1 {
47+
logger.Debug(t.Name(), namespace)
48+
if t.Name() != "" && len(namespace) > 1 {
4949
namespace = namespace[1:]
5050
}
5151

52-
getJsonPath(t.Elem(), namespace, &path)
52+
getJsonPath(t, namespace, &path)
5353
insertError(errorsMap, path, value.Tag())
5454
}
5555

api/certificate/certificate.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ type certJson struct {
8787

8888
func AddCert(c *gin.Context) {
8989
var json certJson
90+
9091
if !api.BindAndValid(c, &json) {
9192
return
9293
}
94+
9395
certModel := &model.Cert{
9496
Name: json.Name,
9597
SSLCertificatePath: json.SSLCertificatePath,

api/system/settings.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ func SaveSettings(c *gin.Context) {
2727
return
2828
}
2929

30-
// todo: omit protected fields when binding
3130
fillSettings(&settings.ServerSettings, &json.Server)
3231
fillSettings(&settings.NginxSettings, &json.Nginx)
3332
fillSettings(&settings.OpenAISettings, &json.Openai)

app/src/views/preference/BasicSettings.vue

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script setup lang="ts">
22
import { useGettext } from 'vue3-gettext'
33
import { inject } from 'vue'
4-
import type { IData } from '@/views/preference/typedef'
4+
import type { Settings } from '@/views/preference/typedef'
55
66
const { $gettext } = useGettext()
7-
const data: IData = inject('data') as IData
7+
const data: Settings = inject('data') as Settings
8+
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
89
</script>
910

1011
<template>
@@ -30,13 +31,25 @@ const data: IData = inject('data') as IData
3031
<AFormItem :label="$gettext('HTTP Challenge Port')">
3132
<AInputNumber v-model:value="data.server.http_challenge_port" />
3233
</AFormItem>
33-
<AFormItem :label="$gettext('Github Proxy')">
34+
<AFormItem
35+
:label="$gettext('Github Proxy')"
36+
:validate-status="errors?.server?.github_proxy ? 'error' : ''"
37+
:help="errors?.server?.github_proxy === 'url'
38+
? $gettext('The url is not valid')
39+
: ''"
40+
>
3441
<AInput
3542
v-model:value="data.server.github_proxy"
36-
:placeholder="$gettext('Chinese user: https://mirror.ghproxy.com/')"
43+
:placeholder="$gettext('For Chinese user: https://mirror.ghproxy.com/')"
3744
/>
3845
</AFormItem>
39-
<AFormItem :label="$gettext('CADir')">
46+
<AFormItem
47+
:label="$gettext('CADir')"
48+
:validate-status="errors?.server?.ca_dir ? 'error' : ''"
49+
:help="errors?.server?.ca_dir === 'url'
50+
? $gettext('The url is not valid')
51+
: ''"
52+
>
4053
<AInput v-model:value="data.server.ca_dir" />
4154
</AFormItem>
4255
</AForm>

app/src/views/preference/NginxSettings.vue

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
<script setup lang="ts">
22
import { useGettext } from 'vue3-gettext'
33
import { inject } from 'vue'
4-
import type { IData } from '@/views/preference/typedef'
4+
import type { Settings } from '@/views/preference/typedef'
55
66
const { $gettext } = useGettext()
77
8-
const data: IData = inject('data')!
8+
const data: Settings = inject('data')!
9+
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
910
</script>
1011

1112
<template>
1213
<AForm layout="vertical">
13-
<AFormItem :label="$gettext('Nginx Access Log Path')">
14+
<AFormItem
15+
:label="$gettext('Nginx Access Log Path')"
16+
:validate-status="errors?.nginx?.access_log_path ? 'error' : ''"
17+
:help="errors?.nginx?.access_log_path === 'file'
18+
? $gettext('File not found')
19+
: ''"
20+
>
1421
<AInput v-model:value="data.nginx.access_log_path" />
1522
</AFormItem>
16-
<AFormItem :label="$gettext('Nginx Error Log Path')">
23+
<AFormItem
24+
:label="$gettext('Nginx Error Log Path')"
25+
:validate-status="errors?.nginx?.error_log_path ? 'error' : ''"
26+
:help="errors?.nginx?.error_log_path === 'file'
27+
? $gettext('File not found')
28+
: ''"
29+
>
1730
<AInput v-model:value="data.nginx.error_log_path" />
1831
</AFormItem>
1932
</AForm>

app/src/views/preference/OpenAISettings.vue

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<script setup lang="ts">
22
import { useGettext } from 'vue3-gettext'
33
import { inject } from 'vue'
4-
import type { IData } from '@/views/preference/typedef'
4+
import type { Settings } from '@/views/preference/typedef'
55
66
const { $gettext } = useGettext()
77
8-
const data: IData = inject('data')!
8+
const data: Settings = inject('data')!
9+
const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
910
</script>
1011

1112
<template>
@@ -26,19 +27,37 @@ const data: IData = inject('data')!
2627
</ASelectOption>
2728
</ASelect>
2829
</AFormItem>
29-
<AFormItem :label="$gettext('API Base Url')">
30+
<AFormItem
31+
:label="$gettext('API Base Url')"
32+
:validate-status="errors?.openai?.base_url ? 'error' : ''"
33+
:help="errors?.openai?.base_url === 'url'
34+
? $gettext('The url is not valid')
35+
: ''"
36+
>
3037
<AInput
3138
v-model:value="data.openai.base_url"
3239
:placeholder="$gettext('Leave blank for the default: https://api.openai.com/')"
3340
/>
3441
</AFormItem>
35-
<AFormItem :label="$gettext('API Proxy')">
42+
<AFormItem
43+
:label="$gettext('API Proxy')"
44+
:validate-status="errors?.openai?.proxy ? 'error' : ''"
45+
:help="errors?.openai?.proxy === 'url'
46+
? $gettext('The url is not valid')
47+
: ''"
48+
>
3649
<AInput
3750
v-model:value="data.openai.proxy"
3851
placeholder="http://127.0.0.1:1087"
3952
/>
4053
</AFormItem>
41-
<AFormItem :label="$gettext('API Token')">
54+
<AFormItem
55+
:label="$gettext('API Token')"
56+
:validate-status="errors?.openai?.token ? 'error' : ''"
57+
:help="errors?.openai?.token === 'alphanumdash'
58+
? $gettext('Token is not valid')
59+
: ''"
60+
>
4261
<AInputPassword v-model:value="data.openai.token" />
4362
</AFormItem>
4463
</AForm>

app/src/views/preference/Preference.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
<script setup lang="ts">
22
import { useGettext } from 'vue3-gettext'
33
import { message } from 'ant-design-vue'
4+
import type { Ref } from 'vue'
45
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
56
import settings from '@/api/settings'
67
import BasicSettings from '@/views/preference/BasicSettings.vue'
78
import OpenAISettings from '@/views/preference/OpenAISettings.vue'
89
import NginxSettings from '@/views/preference/NginxSettings.vue'
9-
import type { IData } from '@/views/preference/typedef'
10+
import type { Settings } from '@/views/preference/typedef'
1011
1112
const { $gettext } = useGettext()
1213
13-
const data = ref<IData>({
14+
const data = ref<Settings>({
1415
server: {
1516
http_host: '0.0.0.0',
1617
http_port: '9000',
@@ -50,18 +51,23 @@ settings.get().then(r => {
5051
data.value = r
5152
})
5253
54+
const errors = ref({}) as Ref<Record<string, Record<string, string>>>
55+
5356
async function save() {
5457
// fix type
5558
data.value.server.http_challenge_port = data.value.server.http_challenge_port.toString()
5659
settings.save(data.value).then(r => {
5760
data.value = r
5861
message.success($gettext('Save successfully'))
62+
errors.value = {}
5963
}).catch(e => {
64+
errors.value = e.errors
6065
message.error(e?.message ?? $gettext('Server error'))
6166
})
6267
}
6368
6469
provide('data', data)
70+
provide('errors', errors)
6571
6672
const router = useRouter()
6773
const route = useRoute()

app/src/views/preference/typedef.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export interface IData {
1+
export interface Settings {
22
server: {
33
http_host: string
44
http_port: string

0 commit comments

Comments
 (0)