16
16
using Semver ;
17
17
using ServerlessWorkflow . Sdk . Models ;
18
18
using Synapse . Api . Client . Services ;
19
- using Synapse . Dashboard . Components . DocumentDetailsStateManagement ;
20
- using Synapse . Dashboard . Components . ResourceEditorStateManagement ;
21
19
using Synapse . Resources ;
20
+ using System . Text . RegularExpressions ;
22
21
23
22
namespace Synapse . Dashboard . Pages . Workflows . Create ;
24
23
@@ -50,7 +49,8 @@ MonacoInterop monacoInterop
50
49
51
50
private TextModel ? _textModel = null ;
52
51
private string _textModelUri = string . Empty ;
53
- private bool _disposed ;
52
+ private bool _disposed = false ;
53
+ private bool _processingVersion = false ;
54
54
55
55
/// <summary>
56
56
/// Gets the service used to perform logging
@@ -122,6 +122,10 @@ MonacoInterop monacoInterop
122
122
/// Gets an <see cref="IObservable{T}"/> used to observe changes to the state's <see cref="CreateWorkflowViewState.WorkflowDefinition"/> property
123
123
/// </summary>
124
124
public IObservable < WorkflowDefinition ? > WorkflowDefinition => this . Select ( state => state . WorkflowDefinition ) . DistinctUntilChanged ( ) ;
125
+ /// <summary>
126
+ /// Gets an <see cref="IObservable{T}"/> used to observe changes to the state's <see cref="CreateWorkflowViewState.WorkflowDefinitionText"/> property
127
+ /// </summary>
128
+ public IObservable < string ? > WorkflowDefinitionText => this . Select ( state => state . WorkflowDefinitionText ) . DistinctUntilChanged ( ) ;
125
129
126
130
/// <summary>
127
131
/// Gets an <see cref="IObservable{T}"/> used to observe changes to the state's <see cref="CreateWorkflowViewState.Loading"/> property
@@ -296,16 +300,17 @@ public async Task OnTextBasedEditorInitAsync()
296
300
/// <returns></returns>
297
301
public async Task SetTextBasedEditorLanguageAsync ( )
298
302
{
303
+ if ( this . TextEditor == null )
304
+ {
305
+ return ;
306
+ }
299
307
try
300
308
{
301
309
var language = this . MonacoEditorHelper . PreferredLanguage ;
302
- if ( this . TextEditor != null )
303
- {
304
- this . _textModel = await Global . GetModel ( this . JSRuntime , this . _textModelUri ) ;
305
- this . _textModel ??= await Global . CreateModel ( this . JSRuntime , "" , language , this . _textModelUri ) ;
306
- await Global . SetModelLanguage ( this . JSRuntime , this . _textModel , language ) ;
307
- await this . TextEditor ! . SetModel ( this . _textModel ) ;
308
- }
310
+ this . _textModel = await Global . GetModel ( this . JSRuntime , this . _textModelUri ) ;
311
+ this . _textModel ??= await Global . CreateModel ( this . JSRuntime , "" , language , this . _textModelUri ) ;
312
+ await Global . SetModelLanguage ( this . JSRuntime , this . _textModel , language ) ;
313
+ await this . TextEditor ! . SetModel ( this . _textModel ) ;
309
314
}
310
315
catch ( Exception ex )
311
316
{
@@ -320,19 +325,33 @@ public async Task SetTextBasedEditorLanguageAsync()
320
325
async Task SetTextEditorValueAsync ( )
321
326
{
322
327
var document = this . Get ( state => state . WorkflowDefinitionText ) ;
323
- if ( this . TextEditor != null && ! string . IsNullOrWhiteSpace ( document ) )
328
+ if ( this . TextEditor == null || string . IsNullOrWhiteSpace ( document ) )
324
329
{
325
- await this . TextEditor . SetValue ( document ) ;
326
- try
327
- {
328
- //await this.TextEditor.Trigger("", "editor.action.triggerSuggest");
329
- await this . TextEditor . Trigger ( "" , "editor.action.formatDocument" ) ;
330
- }
331
- catch ( Exception ex )
332
- {
333
- this . Logger . LogError ( "Unable to set text editor value: {exception}" , ex . ToString ( ) ) ;
334
- }
330
+ return ;
335
331
}
332
+ await this . TextEditor . SetValue ( document ) ;
333
+ try
334
+ {
335
+ await this . TextEditor . Trigger ( "" , "editor.action.formatDocument" ) ;
336
+ }
337
+ catch ( Exception ex )
338
+ {
339
+ this . Logger . LogError ( "Unable to set text editor value: {exception}" , ex . ToString ( ) ) ;
340
+ }
341
+ }
342
+
343
+ /// <summary>
344
+ /// Handles text editor content changes
345
+ /// </summary>
346
+ /// <param name="e">The <see cref="ModelContentChangedEvent"/></param>
347
+ /// <returns>An awaitable task</returns>
348
+ public async Task OnDidChangeModelContent ( ModelContentChangedEvent e )
349
+ {
350
+ if ( this . TextEditor == null ) return ;
351
+ var document = await this . TextEditor . GetValue ( ) ;
352
+ this . Reduce ( state => state with {
353
+ WorkflowDefinitionText = document
354
+ } ) ;
336
355
}
337
356
338
357
/// <summary>
@@ -446,10 +465,6 @@ public override async Task InitializeAsync()
446
465
string document = "" ;
447
466
if ( definition != null )
448
467
{
449
- if ( definition . Document ? . Dsl != null )
450
- {
451
- await this . SetValidationSchema ( $ "v{ definition . Document . Dsl } ") ;
452
- }
453
468
document = this . MonacoEditorHelper . PreferredLanguage == PreferredLanguage . JSON ?
454
469
this . JsonSerializer . SerializeToText ( definition ) :
455
470
this . YamlSerializer . SerializeToText ( definition ) ;
@@ -468,6 +483,25 @@ public override async Task InitializeAsync()
468
483
{
469
484
await this . GetWorkflowDefinitionAsync ( workflow . ns , workflow . name ) ;
470
485
} , cancellationToken : this . CancellationTokenSource . Token ) ;
486
+ this . WorkflowDefinitionText . Where ( document => ! string . IsNullOrEmpty ( document ) ) . Throttle ( new ( 100 ) ) . SubscribeAsync ( async ( document ) => {
487
+ if ( string . IsNullOrWhiteSpace ( document ) )
488
+ {
489
+ return ;
490
+ }
491
+ var currentDslVersion = this . Get ( state => state . DslVersion ) ;
492
+ var versionExtractor = new Regex ( "'?\" ?(dsl|DSL)'?\" ?\\ s*:\\ s*'?\" ?([\\ w\\ .\\ -\\ +]*)'?\" ?" ) ;
493
+ var match = versionExtractor . Match ( document ) ;
494
+ if ( match == null )
495
+ {
496
+ return ;
497
+ }
498
+ var documentDslVersion = match . Groups [ 2 ] . Value ;
499
+ if ( documentDslVersion == currentDslVersion )
500
+ {
501
+ return ;
502
+ }
503
+ await this . SetValidationSchema ( "v" + documentDslVersion ) ;
504
+ } , cancellationToken : this . CancellationTokenSource . Token ) ;
471
505
await base . InitializeAsync ( ) ;
472
506
}
473
507
@@ -479,10 +513,34 @@ public override async Task InitializeAsync()
479
513
protected async Task SetValidationSchema ( string ? version = null )
480
514
{
481
515
version ??= await this . SpecificationSchemaManager . GetLatestVersion ( ) ;
482
- var schema = await this . SpecificationSchemaManager . GetSchema ( version ) ;
483
- var type = $ "create_{ typeof ( WorkflowDefinition ) . Name . ToLower ( ) } _{ version } ";
484
- await this . MonacoInterop . AddValidationSchemaAsync ( schema , $ "https://synapse.io/schemas/{ type } .json", $ "{ type } *") . ConfigureAwait ( false ) ;
485
- this . _textModelUri = this . MonacoEditorHelper . GetResourceUri ( type ) ;
516
+ var currentVersion = this . Get ( state => state . DslVersion ) ;
517
+ if ( currentVersion == version )
518
+ {
519
+ return ;
520
+ }
521
+ if ( this . _processingVersion )
522
+ {
523
+ return ;
524
+ }
525
+ this . SetProblemDetails ( null ) ;
526
+ this . _processingVersion = true ;
527
+ try
528
+ {
529
+ var schema = await this . SpecificationSchemaManager . GetSchema ( version ) ;
530
+ var type = $ "create_{ typeof ( WorkflowDefinition ) . Name . ToLower ( ) } _{ version } _schema";
531
+ await this . MonacoInterop . AddValidationSchemaAsync ( schema , $ "https://synapse.io/schemas/{ type } .json", $ "{ type } *") . ConfigureAwait ( false ) ;
532
+ this . _textModelUri = this . MonacoEditorHelper . GetResourceUri ( type ) ;
533
+ this . Reduce ( state => state with
534
+ {
535
+ DslVersion = version
536
+ } ) ;
537
+ }
538
+ catch ( Exception ex )
539
+ {
540
+ this . Logger . LogError ( "Unable to set the validation schema: {exception}" , ex . ToString ( ) ) ;
541
+ this . SetProblemDetails ( new ProblemDetails ( new Uri ( "about:blank" ) , "Unable to set the validation schema" , 404 , $ "Unable to set the validation schema for the specification version '{ version } '. Make sure the version exists.") ) ;
542
+ }
543
+ this . _processingVersion = false ;
486
544
}
487
545
488
546
/// <summary>
0 commit comments