Skip to content

Commit

Permalink
Any change to proces data model file and initialization script are sa…
Browse files Browse the repository at this point in the history
…ved as change are done

1. When editing data model files or initialization script files for projects, we are currently saving changes only locally. The changes are actually pushed to service only when we do a File -> Save. We will immediately push the changes if the user clicks save on the code/script editor after editing data model or initialization script files. If user chooes cancel, changes will be discarded.
2. When deleting a component which can have scripts associated with them, we show a dialog that let users to decide if they would like to delete the scripts as well. We are only deleting these scripts locally only. These scripts will be deleted in the backend as well now if user decides to delete them.
3. When creating a new project, save the process, datamodel and initialization script file immediately after loading the project for the first time.
  • Loading branch information
Nfactor26 committed Nov 19, 2022
1 parent 6b9b05c commit 7a7e88a
Show file tree
Hide file tree
Showing 25 changed files with 408 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,47 @@ public override async Task EditDataModelAsync()
{
logger.Information($"Opening code editor for editing data model for project : {this.CurrentProject.Name}");
var editorFactory = this.EntityManager.GetServiceOfType<ICodeEditorFactory>();
var projectFileSystem = this.projectManager.GetProjectFileSystem();
using (var editor = editorFactory.CreateMultiCodeEditorScreen())
{
foreach (var file in Directory.GetFiles(this.projectManager.GetProjectFileSystem().DataModelDirectory, "*.cs"))
foreach (var file in Directory.GetFiles(projectFileSystem.DataModelDirectory, "*.cs"))
{
await editor.AddDocumentAsync(Path.GetFileName(file), this.CurrentProject.Name, File.ReadAllText(file), false);
}

await editor.AddDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name, string.Empty, false);
await editor.OpenDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name);

await editor.OpenDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name);
bool? hasChanges = await this.windowManager.ShowDialogAsync(editor);
var editorDocumentStates = editor.GetCurrentEditorState();

if (hasChanges.HasValue && !hasChanges.Value)
{
logger.Information("Discarding changes for data model files");
foreach (var document in editorDocumentStates)
{
if(document.IsNewDocument)
{
File.Delete(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
logger.Information("Delete file {@0} from data model files", document);
}
}
return;
}
}
logger.Information($"Editing data model completed for project : {this.CurrentProject.Name}");


foreach (var document in editorDocumentStates)
{
if ((document.IsNewDocument || document.IsModified) && !document.IsDeleted)
{
await this.projectManager.AddOrUpdateDataFileAsync(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
}
if(document.IsDeleted && !document.IsNewDocument)
{
await this.projectManager.DeleteDataFileAsync(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
}
logger.Information("Updated state of data model file {@0}", document);
}
}
await this.Reload();
}
catch (Exception ex)
Expand Down Expand Up @@ -155,6 +178,8 @@ public async Task EditScriptAsync()
var scriptEngine = entityManager.GetScriptEngine();
scriptEngine.ClearState();
await scriptEngine.ExecuteFileAsync(scriptFile);
await this.projectManager.AddOrUpdateDataFileAsync(scriptFile);
logger.Information("Updated script file : {0}", scriptFile);
}
scriptEditorFactory.RemoveProject(this.CurrentProject.Name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,33 +124,25 @@ private void Initialize()
if (!File.Exists(this.projectFileSystem.ProcessFile))
{
this.RootEntity = new ProcessRootEntity();
this.RootEntity.AddComponent(new ApplicationPoolEntity());
this.RootEntity.AddComponent(new OneTimeSetUpEntity() { Name = "Environment Setup" });
this.RootEntity.AddComponent(new OneTimeTearDownEntity() { Name = "Environment Teardown" });
this.serializer.Serialize<Entity>(this.projectFileSystem.ProcessFile, this.RootEntity);
}
else
{
this.RootEntity = DeserializeProject();
}
AddDefaultEntities();
RestoreParentChildRelation(this.RootEntity);

logger.Information($"Project file for {this.GetProjectName()} has been loaded ");
}

private Entity DeserializeProject()
{
var entity = this.Load<Entity>(this.projectFileSystem.ProcessFile);
return entity;
}


private void AddDefaultEntities()
{
if (this.RootEntity.Components.Count() == 0)
{
this.RootEntity.AddComponent(new ApplicationPoolEntity());
this.RootEntity.AddComponent(new OneTimeSetUpEntity() { Name = "Environment Setup" });
this.RootEntity.AddComponent(new OneTimeTearDownEntity() { Name = "Environment Teardown" });
}
RestoreParentChildRelation(this.RootEntity);
}
}

#endregion Load Project

Expand Down Expand Up @@ -194,6 +186,30 @@ public override async Task Reload()

#region overridden methods

///<inheritdoc/>
public override async Task AddOrUpdateDataFileAsync(string targetFile)
{
await this.projectDataManager.AddOrUpdateDataFileAsync(this.activeProject, this.loadedVersion as ProjectVersion, targetFile, this.activeProject.ProjectId);
}

///<inheritdoc/>
public override async Task DeleteDataFileAsync(string fileToDelete)
{
await this.projectDataManager.DeleteDataFileAsync(this.activeProject, this.loadedVersion as ProjectVersion, fileToDelete);
}

///<inheritdoc/>
protected override string GetProjectName()
{
return this.activeProject.Name;
}

///<inheritdoc/>
protected override string GetProjectNamespace()
{
return this.activeProject.Namespace;
}

/// <summary>
/// Save automation project and process
/// </summary>
Expand Down Expand Up @@ -221,16 +237,6 @@ public override async Task Save()
await this.projectDataManager.SaveProjectDataAsync(this.activeProject, this.loadedVersion as ProjectVersion);
}

protected override string GetProjectName()
{
return this.activeProject.Name;
}

protected override string GetProjectNamespace()
{
return this.activeProject.Namespace;
}

#endregion overridden methods
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public async Task DeleteComponent(ComponentViewModel componentViewModel)
scripts = this.scriptExtractor.ExtractScripts(componentViewModel.Model).ToList();
}

var deleteScriptsViewModel = new DeleteComponentViewModel(componentViewModel, scripts ?? Enumerable.Empty<ScriptStatus>());
var deleteScriptsViewModel = new DeleteComponentViewModel(componentViewModel, scripts ?? Enumerable.Empty<ScriptStatus>(), projectManager);
var result = await this.windowManager.ShowDialogAsync(deleteScriptsViewModel);
if (!result.GetValueOrDefault())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Pixel.Automation.Designer.ViewModels.AutomationBuilder;
using Pixel.Automation.Editor.Core.Interfaces;
using Pixel.Scripting.Editor.Core.Contracts;
using Serilog;
using System.Diagnostics;
using System.IO;
using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;
Expand All @@ -14,6 +15,7 @@ namespace Pixel.Automation.Designer.ViewModels
{
public class PrefabEditorViewModel : EditorViewModel , IPrefabEditor
{
private readonly ILogger logger = Log.ForContext<PrefabEditorViewModel>();
private readonly IServiceResolver serviceResolver;
private readonly IPrefabProjectManager projectManager;

Expand Down Expand Up @@ -60,20 +62,47 @@ public async Task DoLoad(PrefabProject prefabProject, VersionInfo versionToLoad
public override async Task EditDataModelAsync()
{
var editorFactory = this.EntityManager.GetServiceOfType<ICodeEditorFactory>();
var prefabFileSystem = this.projectManager.GetProjectFileSystem();
using (var editor = editorFactory.CreateMultiCodeEditorScreen())
{
foreach (var file in Directory.GetFiles(this.projectManager.GetProjectFileSystem().DataModelDirectory, "*.cs"))
{
await editor.AddDocumentAsync(Path.GetFileName(file), this.PrefabProject.PrefabName, File.ReadAllText(file), false);
}
await editor.AddDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName, string.Empty, false);
await editor.OpenDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName);

await this.windowManager.ShowDialogAsync(editor);
await editor.OpenDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName);

await this.Reload();
}

bool? hasChanges = await this.windowManager.ShowDialogAsync(editor);
var editorDocumentStates = editor.GetCurrentEditorState();

if (hasChanges.HasValue && !hasChanges.Value)
{
logger.Information("Discarding changes for data model files");
foreach (var document in editorDocumentStates)
{
if (document.IsNewDocument)
{
File.Delete(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
logger.Information("Delete file {@0} from data model files", document);
}
}
return;
}

foreach (var document in editorDocumentStates)
{
if ((document.IsNewDocument || document.IsModified) && !document.IsDeleted)
{
await this.projectManager.AddOrUpdateDataFileAsync(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
}
if (document.IsDeleted && !document.IsNewDocument)
{
await this.projectManager.DeleteDataFileAsync(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
}
logger.Information("Updated state of data model file {@0}", document);
}
}
await this.Reload();
}

protected override async Task Reload()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,30 @@ public override async Task Reload()

#region overridden methods

///<inheritdoc/>
public override async Task AddOrUpdateDataFileAsync(string targetFile)
{
await this.prefabDataManager.AddOrUpdateDataFileAsync(this.prefabProject, this.loadedVersion, targetFile, this.prefabProject.PrefabId);
}

///<inheritdoc/>
public override async Task DeleteDataFileAsync(string fileToDelete)
{
await this.prefabDataManager.DeleteDataFileAsync(this.prefabProject, this.loadedVersion, fileToDelete);
}

/// <inheritdoc/>
protected override string GetProjectName()
{
return this.prefabProject.PrefabName;
}

/// <inheritdoc/>
protected override string GetProjectNamespace()
{
return this.prefabProject.Namespace;
}

/// <summary>
/// Save prefab data
/// </summary>
Expand All @@ -234,18 +258,7 @@ public override async Task Save()
}
}

/// <inheritdoc/>
protected override string GetProjectName()
{
return this.prefabProject.PrefabName;
}

/// <inheritdoc/>
protected override string GetProjectNamespace()
{
return this.prefabProject.Namespace;
}


#endregion overridden methods
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,26 @@ public ProjectManager(ISerializer serializer, IEntityManager entityManager, IFil
protected abstract string GetProjectNamespace();

///<inheritdoc/>
public abstract Task Save();
public abstract Task AddOrUpdateDataFileAsync(string targetFile);

///<inheritdoc/>
public abstract Task Reload();
public abstract Task DeleteDataFileAsync(string fileToDelete);

#endregion abstract methods
///<inheritdoc/>
public abstract Task Save();

///<inheritdoc/>
public IProjectManager WithEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager;
this.entityManager.SetCurrentFileSystem(this.fileSystem);
return this;
}
public abstract Task Reload();

#endregion abstract methods

///<inheritdoc/>
public IFileSystem GetProjectFileSystem()
{
return this.fileSystem;
}

///<inheritdoc/>
public IReferenceManager GetReferenceManager()
{
return this.referenceManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Caliburn.Micro;
using Dawn;
using Pixel.Automation.Editor.Core.Interfaces;
using Pixel.Automation.Editor.Core.ViewModels;
using Serilog;
using System.IO;
Expand All @@ -14,7 +15,8 @@ namespace Pixel.Automation.Designer.ViewModels
public class DeleteComponentViewModel : Screen
{
private readonly ILogger logger = Log.ForContext<DeleteComponentViewModel>();

private readonly IProjectManager projectManager;

/// <summary>
/// Component being deleted
/// </summary>
Expand All @@ -25,6 +27,9 @@ public class DeleteComponentViewModel : Screen
/// </summary>
public BindableCollection<SelectableItem<string>> Scripts { get; private set; } = new ();

/// <summary>
/// Indicates if there are any script files associated with the component to delete or it's descendants
/// </summary>
public bool HasScripts
{
get => this.Scripts.Any();
Expand All @@ -35,12 +40,13 @@ public bool HasScripts
/// </summary>
/// <param name="componentViewModel"></param>
/// <param name="scripts"></param>
public DeleteComponentViewModel(ComponentViewModel componentViewModel, IEnumerable<ScriptStatus> scripts)
public DeleteComponentViewModel(ComponentViewModel componentViewModel, IEnumerable<ScriptStatus> scripts, IProjectManager projectManager)
{
this.DisplayName = "Delete Component";
this.componentViewModel = Guard.Argument(componentViewModel).NotNull();
this.componentViewModel = Guard.Argument(componentViewModel, nameof(componentViewModel)).NotNull();
Guard.Argument(scripts).NotNull();
this.Scripts.AddRange(scripts.Select(s => new SelectableItem<string>(s.ScriptName, true)));
this.Scripts.AddRange(scripts.Select(s => new SelectableItem<string>(s.ScriptName, true)));
this.projectManager = Guard.Argument(projectManager, nameof(projectManager)).NotNull().Value;
}

/// <summary>
Expand All @@ -56,8 +62,9 @@ public async Task Delete()
{
if(script.IsSelected)
{
File.Delete(Path.Combine(fileSystem.WorkingDirectory, script.Item));
logger.Information($"Deleted script file {script.Item}");
await this.projectManager.DeleteDataFileAsync(Path.Combine(fileSystem.WorkingDirectory, script.Item));
logger.Information("Script File '{0}' was deleted", script.Item);

}
}
catch (Exception ex)
Expand Down
Loading

0 comments on commit 7a7e88a

Please sign in to comment.