1919using Synapse . Api . Client . Services ;
2020using Synapse . Dashboard . Pages . Workflows . List ;
2121using Synapse . Resources ;
22+ using System . Reflection . Emit ;
2223using System . Text . RegularExpressions ;
24+ using static Synapse . SynapseDefaults . Resources ;
2325
2426namespace Synapse . Dashboard . Pages . Workflows . Create ;
2527
@@ -177,10 +179,15 @@ IWorkflowDefinitionValidator workflowDefinitionValidator
177179 /// </summary>
178180 public IObservable < EquatableList < Operator > ? > Operators => this . Select ( s => s . Operators ) . DistinctUntilChanged ( ) ;
179181
182+ /// <summary>
183+ /// Gets an <see cref="IObservable{T}"/> used to observe <see cref="CreateWorkflowViewState.Labels"/> changes
184+ /// </summary>
185+ public IObservable < EquatableDictionary < string , string > > Labels => this . Select ( state => state . Labels ) . DistinctUntilChanged ( ) ;
186+
180187 /// <summary>
181188 /// Gets an <see cref="IObservable{T}"/> used to observe <see cref="WorkflowListState.Operator"/> changes
182189 /// </summary>
183- public IObservable < string ? > Operator => this . Select ( s => s . Operator ) . DistinctUntilChanged ( ) ;
190+ public IObservable < string ? > Operator => this . Select ( state => state . Labels . TryGetValue ( SynapseDefaults . Resources . Labels . Operator , out var label ) ? label : null ) . DistinctUntilChanged ( ) ;
184191
185192 /// <summary>
186193 /// Gets an <see cref="IObservable{T}"/> used to observe computed <see cref="Neuroglia.ProblemDetails"/>
@@ -270,15 +277,15 @@ public async Task GetWorkflowDefinitionAsync(string @namespace, string name)
270277 ArgumentException . ThrowIfNullOrWhiteSpace ( @namespace ) ;
271278 ArgumentException . ThrowIfNullOrWhiteSpace ( name ) ;
272279 var workflow = await Api . Workflows . GetAsync ( name , @namespace ) ?? throw new NullReferenceException ( $ "Failed to find the specified workflow '{ name } .{ @namespace } '") ;
273- var operatorName = workflow . Metadata . Labels ? . Get ( SynapseDefaults . Resources . Labels . Operator ) ;
280+ // var operatorName = workflow.Metadata.Labels?.Get(SynapseDefaults.Resources.Labels.Operator);
274281 var definition = workflow . Spec . Versions . GetLatest ( ) ;
275282 var nextVersion = SemVersion . Parse ( definition . Document . Version , SemVersionStyles . Strict ) ;
276283 nextVersion = nextVersion . WithPatch ( nextVersion . Patch + 1 ) ;
277284 definition . Document . Version = nextVersion . ToString ( ) ;
278285 Reduce ( s => s with
279286 {
280287 WorkflowDefinition = definition ,
281- Operator = operatorName ,
288+ Labels = workflow . Metadata . Labels != null ? [ .. workflow . Metadata . Labels ] : [ ] ,
282289 Loading = false
283290 } ) ;
284291 }
@@ -439,7 +446,7 @@ public async Task SaveWorkflowDefinitionAsync()
439446 var name = workflowDefinition . Document . Name ;
440447 var version = workflowDefinition . Document . Version ;
441448 var isNew = Get ( state => state . IsNew ) ;
442- var operatorName = Get ( state => state . Operator ) ;
449+ var labels = Get ( state => state . Labels ) ;
443450 Reduce ( s => s with
444451 {
445452 Saving = true
@@ -460,11 +467,7 @@ public async Task SaveWorkflowDefinitionAsync()
460467 Versions = [ workflowDefinition ]
461468 }
462469 } ;
463- if ( ! string . IsNullOrWhiteSpace ( operatorName ) )
464- {
465- workflow . Metadata . Labels = workflow . Metadata . Labels ?? new EquatableDictionary < string , string > ( ) ;
466- workflow . Metadata . Labels . Add ( SynapseDefaults . Resources . Labels . Operator , operatorName ) ;
467- }
470+ if ( labels . Count > 0 ) workflow . Metadata . Labels = labels ;
468471 workflow = await Api . Workflows . CreateAsync ( workflow ) ;
469472 NavigationManager . NavigateTo ( $ "/workflows/details/{ @namespace } /{ name } /{ version } ") ;
470473 return ;
@@ -487,11 +490,7 @@ public async Task SaveWorkflowDefinitionAsync()
487490 } ) ;
488491 return ;
489492 }
490- if ( ! string . IsNullOrWhiteSpace ( operatorName ) && updatedResource . Metadata . Labels ? . Get ( SynapseDefaults . Resources . Labels . Operator ) != operatorName )
491- {
492- updatedResource . Metadata . Labels ??= new EquatableDictionary < string , string > ( ) ;
493- updatedResource . Metadata . Labels [ SynapseDefaults . Resources . Labels . Operator ] = operatorName ;
494- }
493+ updatedResource . Metadata . Labels = labels ;
495494 updatedResource . Spec . Versions . Add ( workflowDefinition ! ) ;
496495 var jsonPatch = JsonPatch . FromDiff ( JsonSerializer . SerializeToElement ( workflow ) ! . Value , JsonSerializer . SerializeToElement ( updatedResource ) ! . Value ) ;
497496 var patch = JsonSerializer . Deserialize < Json . Patch . JsonPatch > ( jsonPatch . RootElement ) ;
@@ -567,16 +566,66 @@ public async Task ListOperatorsAsync()
567566 } ) ;
568567 }
569568
569+ /// <summary>
570+ /// Sets the workflow labels
571+ /// </summary>
572+ /// <param name="labels">The new labels</param>
573+ public virtual void SetLabels ( EquatableDictionary < string , string > ? labels )
574+ {
575+ this . Reduce ( state => state with
576+ {
577+ Labels = labels != null ? [ ..labels ] : [ ]
578+ } ) ;
579+ }
580+
581+ /// <summary>
582+ /// Adds a single label
583+ /// </summary>
584+ /// <param name="key">The key of the label</param>
585+ /// <param name="value">The value of the label</param>
586+ public virtual void AddLabel ( string key , string value )
587+ {
588+ if ( string . IsNullOrEmpty ( key ) || string . IsNullOrEmpty ( value ) )
589+ {
590+ return ;
591+ }
592+ var labels = new EquatableDictionary < string , string > ( this . Get ( state => state . Labels ) ) ;
593+ if ( labels . ContainsKey ( key ) )
594+ {
595+ labels . Remove ( key ) ;
596+ }
597+ labels . Add ( key , value ) ;
598+ this . SetLabels ( labels ) ;
599+ }
600+
601+ /// <summary>
602+ /// Removes a single label using it's key
603+ /// </summary>
604+ /// <param name="key">The label selector key to remove</param>
605+ public void RemoveLabel ( string key )
606+ {
607+ if ( string . IsNullOrWhiteSpace ( key ) )
608+ {
609+ return ;
610+ }
611+ var labels = new EquatableDictionary < string , string > ( this . Get ( state => state . Labels ) ) ;
612+ if ( labels . ContainsKey ( key ) )
613+ {
614+ labels . Remove ( key ) ;
615+ }
616+ this . SetLabels ( labels ) ;
617+ }
618+
570619 /// <summary>
571620 /// Sets the <see cref="WorkflowListState.Operator"/>
572621 /// </summary>
573622 /// <param name="operatorName">The new value</param>
574623 public void SetOperator ( string ? operatorName )
575624 {
576- Reduce ( state => state with
577- {
578- Operator = operatorName
579- } ) ;
625+ if ( string . IsNullOrEmpty ( operatorName ) )
626+ RemoveLabel ( SynapseDefaults . Resources . Labels . Operator ) ;
627+ else
628+ AddLabel ( SynapseDefaults . Resources . Labels . Operator , operatorName ) ;
580629 }
581630 #endregion
582631
0 commit comments