11import { get , set } from 'es-toolkit/compat'
22import { marked } from 'marked'
3- import { NDynamicTags , NInput , NInputNumber , NSelect , NSwitch } from 'naive-ui'
4- import { defineComponent , ref , watch , watchEffect } from 'vue'
5- import type { PropType , Ref } from 'vue'
3+ import {
4+ NButton ,
5+ NDynamicTags ,
6+ NInput ,
7+ NInputNumber ,
8+ NSelect ,
9+ NSwitch ,
10+ } from 'naive-ui'
11+ import { defineComponent , inject , provide , ref , watch , watchEffect } from 'vue'
12+ import type { InjectionKey , PropType , Ref } from 'vue'
613import type { FormField } from './types'
714
815import { SettingsItem } from '~/layouts/settings-layout'
916import { uuid } from '~/utils'
1017
18+ export type ActionHandler = ( actionId : string ) => void
19+ export const ActionHandlerKey : InjectionKey < ActionHandler > = Symbol (
20+ 'config-form-action-handler' ,
21+ )
22+
23+ /**
24+ * Compare values for showWhen conditions.
25+ * Handles boolean/string coercion for values like { aiReview: 'true' }
26+ */
27+ function matchShowWhenValue ( actualValue : unknown , expected : unknown ) : boolean {
28+ if ( actualValue === expected ) return true
29+ if ( typeof actualValue === 'boolean' && typeof expected === 'string' ) {
30+ return String ( actualValue ) === expected
31+ }
32+ if ( typeof actualValue === 'string' && typeof expected === 'boolean' ) {
33+ return actualValue === String ( expected )
34+ }
35+ return false
36+ }
37+
1138/**
1239 * Check if a field should be shown based on showWhen conditions.
1340 * When the condition is not met, the field and all its nested children are hidden.
@@ -23,9 +50,11 @@ function shouldShowField(
2350 for ( const [ key , expected ] of Object . entries ( showWhen ) ) {
2451 const actualValue = get ( formData . value , `${ sectionPrefix } .${ key } ` )
2552 if ( Array . isArray ( expected ) ) {
26- if ( ! expected . includes ( actualValue ) ) return false
53+ if ( ! expected . some ( ( exp ) => matchShowWhenValue ( actualValue , exp ) ) ) {
54+ return false
55+ }
2756 } else {
28- if ( actualValue !== expected ) return false
57+ if ( ! matchShowWhenValue ( actualValue , expected ) ) return false
2958 }
3059 }
3160 return true
@@ -45,8 +74,18 @@ export const SectionFields = defineComponent({
4574 type : String ,
4675 required : true ,
4776 } ,
77+ onAction : {
78+ type : Function as PropType < ActionHandler > ,
79+ } ,
4880 } ,
4981 setup ( props ) {
82+ const parentHandler = inject ( ActionHandlerKey , undefined )
83+ const handler = props . onAction || parentHandler
84+
85+ if ( handler ) {
86+ provide ( ActionHandlerKey , handler )
87+ }
88+
5089 return ( ) => {
5190 const { fields, formData, dataKeyPrefix } = props
5291
@@ -111,6 +150,7 @@ export const FormFieldItem = defineComponent({
111150 } ,
112151 setup ( props ) {
113152 const innerValue = ref ( props . value )
153+ const actionHandler = inject ( ActionHandlerKey , undefined )
114154
115155 watch (
116156 ( ) => props . value ,
@@ -133,7 +173,7 @@ export const FormFieldItem = defineComponent({
133173 < NInput
134174 inputProps = { { id : uuid ( ) } }
135175 value = { innerValue . value }
136- onUpdateValue = { ( val ) => {
176+ onUpdateValue = { ( val : string | null ) => {
137177 innerValue . value = val
138178 } }
139179 placeholder = { ui . placeholder }
@@ -146,7 +186,7 @@ export const FormFieldItem = defineComponent({
146186 < NInput
147187 inputProps = { { id : uuid ( ) } }
148188 value = { innerValue . value }
149- onUpdateValue = { ( val ) => {
189+ onUpdateValue = { ( val : string | null ) => {
150190 innerValue . value = val
151191 } }
152192 type = "password"
@@ -161,7 +201,7 @@ export const FormFieldItem = defineComponent({
161201 < NInput
162202 inputProps = { { id : uuid ( ) } }
163203 value = { innerValue . value }
164- onUpdateValue = { ( val ) => {
204+ onUpdateValue = { ( val : string | null ) => {
165205 innerValue . value = val
166206 } }
167207 type = "textarea"
@@ -175,7 +215,7 @@ export const FormFieldItem = defineComponent({
175215 return (
176216 < NInputNumber
177217 value = { innerValue . value }
178- onUpdateValue = { ( val ) => {
218+ onUpdateValue = { ( val : number | null ) => {
179219 innerValue . value = val
180220 } }
181221 placeholder = { ui . placeholder }
@@ -186,7 +226,7 @@ export const FormFieldItem = defineComponent({
186226 return (
187227 < NSwitch
188228 value = { innerValue . value }
189- onUpdateValue = { ( val ) => {
229+ onUpdateValue = { ( val : boolean ) => {
190230 innerValue . value = val
191231 } }
192232 />
@@ -196,7 +236,7 @@ export const FormFieldItem = defineComponent({
196236 return (
197237 < NSelect
198238 value = { innerValue . value }
199- onUpdateValue = { ( val ) => {
239+ onUpdateValue = { ( val : string | number | null ) => {
200240 innerValue . value = val
201241 } }
202242 options = { ui . options }
@@ -209,12 +249,27 @@ export const FormFieldItem = defineComponent({
209249 return (
210250 < NDynamicTags
211251 value = { innerValue . value }
212- onUpdateValue = { ( val ) => {
252+ onUpdateValue = { ( val : string [ ] ) => {
213253 innerValue . value = val
214254 } }
215255 />
216256 )
217257
258+ case 'action' :
259+ return (
260+ < NButton
261+ size = "small"
262+ secondary
263+ onClick = { ( ) => {
264+ if ( ui . actionId && actionHandler ) {
265+ actionHandler ( ui . actionId )
266+ }
267+ } }
268+ >
269+ { ui . actionLabel || field . title }
270+ </ NButton >
271+ )
272+
218273 default :
219274 return null
220275 }
0 commit comments