@@ -31,6 +31,22 @@ const meta: Meta<TArgs> = {
3131 description :
3232 "data.value – template resolved via parseWithoutPartsOfUrl (e.g. \"{reqsJsonPath[0]['.data.flag']['-']}\")" ,
3333 } ,
34+ criteria : {
35+ control : { type : 'radio' } ,
36+ options : [ 'equals' , 'notEquals' , 'exists' , 'notExists' , null ] ,
37+ mapping : {
38+ equals : 'equals' ,
39+ notEquals : 'notEquals' ,
40+ exists : 'exists' ,
41+ notExists : 'notExists' ,
42+ null : undefined ,
43+ } ,
44+ description : 'data.criteria – optional comparison operator (equals / notEquals / exists / notExists)' ,
45+ } ,
46+ valueToCompare : {
47+ control : 'object' ,
48+ description : 'data.valueToCompare – string or array of strings to compare with resolved value' ,
49+ } ,
3450
3551 // provider knobs
3652 isLoading : {
@@ -56,6 +72,8 @@ const meta: Meta<TArgs> = {
5672 const data : TInner = {
5773 id : args . id ,
5874 value : args . value ,
75+ criteria : args . criteria as TInner [ 'criteria' ] ,
76+ valueToCompare : args . valueToCompare as TInner [ 'valueToCompare' ] ,
5977 }
6078
6179 return (
@@ -76,8 +94,15 @@ const meta: Meta<TArgs> = {
7694 fontSize : 13 ,
7795 } }
7896 >
79- I am only visible when < code > value</ code > resolves to something other than{ ' ' }
80- < code > ~undefined-value~</ code > .
97+ I am visible when:
98+ < ul style = { { marginTop : 6 } } >
99+ < li >
100+ < code > value</ code > resolves (not < code > ~undefined-value~</ code > )
101+ </ li >
102+ < li >
103+ If < code > criteria</ code > is set, the comparison passes against < code > valueToCompare</ code >
104+ </ li >
105+ </ ul >
81106 </ div >
82107 </ VisibilityContainer >
83108 </ div >
@@ -115,6 +140,8 @@ export const Default: Story = {
115140 id : 'example-visibility-container' ,
116141 // typical template used by parseWithoutPartsOfUrl
117142 value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
143+ criteria : undefined ,
144+ valueToCompare : undefined ,
118145
119146 // providers
120147 isLoading : false ,
@@ -152,3 +179,219 @@ export const LoadingMultiQuery: Story = {
152179 isLoading : true ,
153180 } ,
154181}
182+
183+ export const CriteriaEqualsPasses : Story = {
184+ args : {
185+ ...Default . args ,
186+ id : 'visibility-criteria-equals-passes' ,
187+ criteria : 'equals' ,
188+ valueToCompare : [ 'show' ] ,
189+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
190+ multiQueryData : {
191+ req0 : {
192+ data : {
193+ flag : 'show' ,
194+ } ,
195+ } ,
196+ } ,
197+ } ,
198+ }
199+
200+ export const CriteriaEqualsFails : Story = {
201+ args : {
202+ ...Default . args ,
203+ id : 'visibility-criteria-equals-fails' ,
204+ criteria : 'equals' ,
205+ valueToCompare : [ 'Role' ] ,
206+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
207+ multiQueryData : {
208+ req0 : {
209+ data : {
210+ flag : 'ClusterRole' ,
211+ } ,
212+ } ,
213+ } ,
214+ } ,
215+ }
216+
217+ export const CriteriaNotEqualsPasses : Story = {
218+ args : {
219+ ...Default . args ,
220+ id : 'visibility-criteria-not-equals-passes' ,
221+ criteria : 'notEquals' ,
222+ valueToCompare : [ 'Role' ] ,
223+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
224+ multiQueryData : {
225+ req0 : {
226+ data : {
227+ flag : 'ClusterRole' ,
228+ } ,
229+ } ,
230+ } ,
231+ } ,
232+ }
233+
234+ export const CriteriaNotEqualsFails : Story = {
235+ args : {
236+ ...Default . args ,
237+ id : 'visibility-criteria-not-equals-fails' ,
238+ criteria : 'notEquals' ,
239+ valueToCompare : [ 'Role' ] ,
240+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
241+ multiQueryData : {
242+ req0 : {
243+ data : {
244+ flag : 'Role' ,
245+ } ,
246+ } ,
247+ } ,
248+ } ,
249+ }
250+
251+ // ========== NEW: EXISTS / NOT EXISTS CRITERIA ==========
252+
253+ export const CriteriaExistsPasses : Story = {
254+ args : {
255+ ...Default . args ,
256+ id : 'visibility-criteria-exists-passes' ,
257+ criteria : 'exists' ,
258+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
259+ multiQueryData : {
260+ req0 : {
261+ data : {
262+ flag : 'some-value' ,
263+ } ,
264+ } ,
265+ } ,
266+ } ,
267+ }
268+
269+ export const CriteriaExistsFails : Story = {
270+ args : {
271+ ...Default . args ,
272+ id : 'visibility-criteria-exists-fails' ,
273+ criteria : 'exists' ,
274+ value : "{reqsJsonPath[0]['.data.missing']['-']}" ,
275+ multiQueryData : {
276+ req0 : {
277+ data : {
278+ flag : 'show' ,
279+ } ,
280+ } ,
281+ } ,
282+ } ,
283+ }
284+
285+ export const CriteriaNotExistsPasses : Story = {
286+ args : {
287+ ...Default . args ,
288+ id : 'visibility-criteria-not-exists-passes' ,
289+ criteria : 'notExists' ,
290+ value : "{reqsJsonPath[0]['.data.missing']['-']}" ,
291+ multiQueryData : {
292+ req0 : {
293+ data : {
294+ flag : 'show' ,
295+ } ,
296+ } ,
297+ } ,
298+ } ,
299+ }
300+
301+ export const CriteriaNotExistsFails : Story = {
302+ args : {
303+ ...Default . args ,
304+ id : 'visibility-criteria-not-exists-fails' ,
305+ criteria : 'notExists' ,
306+ value : "{reqsJsonPath[0]['.data.flag']['-']}" ,
307+ multiQueryData : {
308+ req0 : {
309+ data : {
310+ flag : 'some-value' ,
311+ } ,
312+ } ,
313+ } ,
314+ } ,
315+ }
316+
317+ // ========== NEW: DYNAMIC valueToCompare WITH parseAll ==========
318+
319+ export const DynamicValueToCompare : Story = {
320+ args : {
321+ ...Default . args ,
322+ id : 'visibility-dynamic-value-to-compare' ,
323+ criteria : 'equals' ,
324+ value : "{reqsJsonPath[0]['.status.phase']['-']}" ,
325+ // valueToCompare uses dynamic template from another request
326+ valueToCompare : [ "{reqsJsonPath[1]['.data.expectedPhase']['-']}" ] ,
327+ multiQueryData : {
328+ req0 : {
329+ status : {
330+ phase : 'Running' ,
331+ } ,
332+ } ,
333+ req1 : {
334+ data : {
335+ expectedPhase : 'Running' ,
336+ } ,
337+ } ,
338+ } ,
339+ } ,
340+ }
341+
342+ export const DynamicValueToCompareWithPartsOfUrl : Story = {
343+ args : {
344+ ...Default . args ,
345+ id : 'visibility-dynamic-value-to-compare-parts-of-url' ,
346+ criteria : 'equals' ,
347+ value : "{reqsJsonPath[0]['.metadata.namespace']['-']}" ,
348+ // valueToCompare uses URL part (e.g., {2} = cluster name from URL)
349+ valueToCompare : [ '{2}' ] ,
350+ partsOfUrl : [ '' , '' , 'default' , 'pods' , 'my-pod' ] ,
351+ multiQueryData : {
352+ req0 : {
353+ metadata : {
354+ namespace : 'default' ,
355+ } ,
356+ } ,
357+ } ,
358+ } ,
359+ }
360+
361+ // ========== NEW: CHECKING AGAINST ~undefined-value~ ==========
362+
363+ export const CheckAgainstUndefinedValue : Story = {
364+ args : {
365+ ...Default . args ,
366+ id : 'visibility-check-undefined-value' ,
367+ criteria : 'equals' ,
368+ value : "{reqsJsonPath[0]['.metadata.deletionTimestamp']['-']}" ,
369+ valueToCompare : [ '~undefined-value~' ] ,
370+ multiQueryData : {
371+ req0 : {
372+ metadata : {
373+ name : 'my-resource' ,
374+ // deletionTimestamp is missing (undefined)
375+ } ,
376+ } ,
377+ } ,
378+ } ,
379+ }
380+
381+ export const CheckNotUndefinedValue : Story = {
382+ args : {
383+ ...Default . args ,
384+ id : 'visibility-check-not-undefined-value' ,
385+ criteria : 'notEquals' ,
386+ value : "{reqsJsonPath[0]['.metadata.deletionTimestamp']['-']}" ,
387+ valueToCompare : [ '~undefined-value~' ] ,
388+ multiQueryData : {
389+ req0 : {
390+ metadata : {
391+ name : 'my-resource' ,
392+ deletionTimestamp : '2024-01-01T00:00:00Z' ,
393+ } ,
394+ } ,
395+ } ,
396+ } ,
397+ }
0 commit comments