@@ -55,7 +55,19 @@ const handleEdit = (index: number) => {
55
55
}
56
56
57
57
const handleUse = (ruleset : any ) => {
58
- fields .value .payload = ruleset .id
58
+ const ids = fields .value .payload .split (' ,' ).filter ((v ) => v )
59
+ const idx = ids .findIndex ((v ) => v === ruleset .id )
60
+ if (idx === - 1 ) {
61
+ ids .push (ruleset .id )
62
+ } else {
63
+ ids .splice (idx , 1 )
64
+ }
65
+ fields .value .payload = ids .join (' ,' )
66
+ }
67
+
68
+ const handleClearRuleset = (ruleset : any ) => {
69
+ const ids = fields .value .payload .split (' ,' ).filter ((id ) => props .ruleSet .find ((v ) => v .id === id ))
70
+ ruleset .payload = ids .join (' ,' )
59
71
}
60
72
61
73
const handleDelete = (index : number ) => {
@@ -69,20 +81,31 @@ const isSupportPayload = computed(() => {
69
81
})
70
82
71
83
const hasLost = (rule : IRule ) => {
72
- if (rule .type === RuleType .Protocol ) {
73
- return false
84
+ const rulesValidationFlags: boolean [] = []
85
+ const hasMissingInbound = ! props .inboundOptions .find ((v ) => v .value === rule .payload )
86
+ const hasMissingOutbound = ! props .outboundOptions .find ((v ) => v .value === rule .outbound )
87
+ const hasMissingRuleset = rule .payload
88
+ .split (' ,' )
89
+ .some ((id ) => ! props .ruleSet .find ((v ) => v .id === id ))
90
+ if (rule .action === RuleAction .Route ) {
91
+ rulesValidationFlags .push (hasMissingOutbound )
92
+ } else if (rule .action === RuleAction .RouteOptions ) {
93
+ let isValid = true
94
+ try {
95
+ JSON .parse (rule .outbound )
96
+ } catch {
97
+ isValid = false
98
+ }
99
+ rulesValidationFlags .push (! isValid )
74
100
}
75
101
if (rule .type === RuleType .Inbound ) {
76
- return ! props .inboundOptions .find ((v ) => v .value === rule .payload )
77
- }
78
- if (rule .action !== RuleAction .Route ) {
79
- return false
80
- }
81
- const outboundLost = ! props .outboundOptions .find ((v ) => v .value === rule .outbound )
82
- if (rule .type === RuleType .RuleSet ) {
83
- return ! props .ruleSet .find ((v ) => v .id === rule .payload ) || outboundLost
102
+ rulesValidationFlags .push (hasMissingInbound )
103
+ } else if (rule .type === RuleType .IpIsPrivate ) {
104
+ rulesValidationFlags .push (! [' true' , ' false' ].includes (rule .payload ))
105
+ } else if (rule .type === RuleType .RuleSet ) {
106
+ rulesValidationFlags .push (hasMissingRuleset )
84
107
}
85
- return outboundLost
108
+ return rulesValidationFlags . some (( v ) => v ) || ! rule . payload
86
109
}
87
110
88
111
const renderRule = (rule : IRule ) => {
@@ -121,7 +144,14 @@ const renderRule = (rule: IRule) => {
121
144
<span v-if =" hasLost(rule)" @click =" showLost" class =" warn" > [ ! ] </span >
122
145
{{ renderRule(rule) }}
123
146
</div >
124
- <div class =" ml-auto" >
147
+ <div class =" flex text-nowrap ml-auto" >
148
+ <Button
149
+ v-if =" rule.type === RuleType.RuleSet && rule.payload && hasLost(rule)"
150
+ @click =" handleClearRuleset(rule)"
151
+ type =" text"
152
+ >
153
+ {{ t('common.clear') }}
154
+ </Button >
125
155
<Button @click =" handleEdit(index)" icon =" edit" type =" text" size =" small" />
126
156
<Button @click =" handleDelete(index)" icon =" delete" type =" text" size =" small" />
127
157
</div >
@@ -227,7 +257,7 @@ const renderRule = (rule: IRule) => {
227
257
:key =" ruleset.tag"
228
258
:title =" ruleset.tag"
229
259
@click =" handleUse(ruleset)"
230
- :selected =" fields.payload === ruleset.id"
260
+ :selected =" fields.payload.includes( ruleset.id) "
231
261
v-tips =" ruleset.type"
232
262
class =" ruleset"
233
263
>
0 commit comments