private void TranslateScript(object parameter)
        {
            if (!(parameter is TreeNodeViewModel parentNode)) return;

            WebServerSettings settings = GetWebServerSettingsForScriptNode(parentNode);
            if (settings == null)
            {
                MessageBox.Show("Web server settings not found!", "1C#", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            string scriptName = parentNode.NodeText;
            string catalogPath = (string)parentNode.NodePayload;
            string scriptFullName = Path.Combine(Module.WebServersCatalogPath, catalogPath, scriptName);
            if (!File.Exists(scriptFullName))
            {
                MessageBox.Show($"Script \"{scriptFullName}\" not found !", "1C#", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }
            // read script file
            string script = File.ReadAllText(scriptFullName);

            // open script for execution
            QueryEditorView view = new QueryEditorView()
            {
                DataContext = new QueryEditorViewModel(Module.Shell, settings, scriptFullName, MetadataService, ScriptingService) { QueryScript = script }
            };
            Module.Shell.AddTabItem(scriptName, view);
        }
        private void CreateWebScript(object parameter)
        {
            if (!(parameter is TreeNodeViewModel parentNode)) return;

            WebServerSettings settings = GetWebServerSettingsForScriptNode(parentNode);
            if (settings == null)
            {
                MessageBox.Show("Web server settings not found!", "1C#", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // ask for query file name
            InputStringDialog dialog = new InputStringDialog()
            {
                Title = "Script name"
            };
            _ = dialog.ShowDialog();
            if (dialog.Result == null) return;

            string scriptName = (string)dialog.Result;
            string catalogPath;
            if (parentNode.NodePayload is WebServerSettings)
            {
                catalogPath = parentNode.NodeText;
            }
            else
            {
                catalogPath = (string)parentNode.NodePayload;
            }
            string scriptFullName = Path.Combine(Module.WebServersCatalogPath, catalogPath, $"{scriptName}.qry");
            if (File.Exists(scriptFullName))
            {
                MessageBox.Show($"Script \"{scriptFullName}\" already exists !", "1C#", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }
            // create query file on the disk
            _ = File.Create(scriptFullName);

            CreateScriptNode(parentNode, $"{scriptName}.qry");

            // open script for editing
            QueryEditorView view = new QueryEditorView()
            {
                DataContext = new QueryEditorViewModel(Module.Shell, settings, scriptFullName, MetadataService, ScriptingService) { QueryScript = "" }
            };
            Module.Shell.AddTabItem($"{scriptName}.qry", view);
        }
        private void Translate(object parameter)
        {
            Metadata.UseServer(Settings.DataHost);
            Metadata.UseDatabase(Settings.Database);
            string sql          = Scripting.PrepareScript(QueryScript, out IList <ParseError> errors);
            string errorMessage = string.Empty;

            foreach (ParseError error in errors)
            {
                errorMessage += error.Message + Environment.NewLine;
            }

            if (errors.Count > 0)
            {
                QueryEditorView view = new QueryEditorView()
                {
                    DataContext = new QueryEditorViewModel(Shell, Settings, FileFullPath, Metadata, Scripting)
                    {
                        QueryScript = errorMessage
                    }
                };
                Shell.AddTabItem("Errors", view);
            }
            else
            {
                FileInfo        file         = new FileInfo(FileFullPath);
                string          fileFullPath = Path.ChangeExtension(FileFullPath, "sql");
                QueryEditorView view         = new QueryEditorView()
                {
                    DataContext = new QueryEditorViewModel(Shell, Settings, fileFullPath, Metadata, Scripting)
                    {
                        QueryScript = sql
                    }
                };
                Shell.AddTabItem(Path.ChangeExtension(file.Name, "sql"), view);
            }
        }
        private void Execute(object parameter)
        {
            string errorMessage = string.Empty;

            Metadata.UseServer(Settings.DataHost);
            Metadata.UseDatabase(Settings.Database);

            string   sql;
            FileInfo file = new FileInfo(FileFullPath);

            if (file.Extension == ".sql")
            {
                sql = QueryScript;
            }
            else
            {
                sql = Scripting.PrepareScript(QueryScript, out IList <ParseError> errors);
                foreach (ParseError error in errors)
                {
                    errorMessage += error.Message + Environment.NewLine;
                }
                if (errors.Count > 0)
                {
                    QueryEditorView errorsView = new QueryEditorView()
                    {
                        DataContext = new QueryEditorViewModel(Shell, Settings, FileFullPath, Metadata, Scripting)
                        {
                            QueryScript = errorMessage
                        }
                    };
                    Shell.AddTabItem("Errors", errorsView);
                    return;
                }
            }
            string json = "[]";

            try
            {
                json = Scripting.ExecuteScript(sql, out IList <ParseError> executeErrors);
                foreach (ParseError error in executeErrors)
                {
                    errorMessage += error.Message + Environment.NewLine;
                }
                if (executeErrors.Count > 0)
                {
                    QueryEditorView errorsView = new QueryEditorView()
                    {
                        DataContext = new QueryEditorViewModel(Shell, Settings, FileFullPath, Metadata, Scripting)
                        {
                            QueryScript = errorMessage
                        }
                    };
                    Shell.AddTabItem("Errors", errorsView);
                    return;
                }
            }
            catch (Exception ex)
            {
                QueryEditorView errorsView = new QueryEditorView()
                {
                    DataContext = new QueryEditorViewModel(Shell, Settings, FileFullPath, Metadata, Scripting)
                    {
                        QueryScript = ex.Message
                    }
                };
                Shell.AddTabItem("Error", errorsView);
                return;
            }
            JsonSerializerOptions serializerOptions = new JsonSerializerOptions();

            serializerOptions.Converters.Add(new DynamicJsonConverter());
            dynamic data = JsonSerializer.Deserialize <dynamic>(json, serializerOptions);

            //QueryEditorView view = new QueryEditorView()
            //{
            //    DataContext = new QueryEditorViewModel(Shell, Settings, FileFullPath, Metadata, Scripting) { QueryScript = json }
            //};
            //Grid view = CreateDynamicGrid(data);
            DataGrid view = CreateDynamicDataGrid(data);

            Shell.AddTabItem($"{file.Name} - result", view);
        }