diff --git a/README.md b/README.md index c229dcd..838c6eb 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Add required `CSS` and `Javascript` packages into the `index.html` file. - [Toast](#toast) - [Toggle](#toggle) - [Tooltip](#tooltip) +- [Tree](#tree) - [Upload](#upload) - [Form Validation](#form-validation) - [Workflow](#workflow) @@ -695,7 +696,67 @@ toast.ShowToast("test message", "info"); ``` -- [ ] Tree +## Tree + +```html +
+ +
+``` + +```csharp +Tree tree; + +Dictionary treeNodes = new(); + +treeNodes.Add("root", new TreeNode() +{ + Id = "root", + HasChildren = true, + Children = new List(){"sample"} +}); + +treeNodes.Add("sample", new TreeNode() +{ + Id = "sample", + Data = new TreeData() + { + Name = "Sample" + }, + HasChildren = true, + Children = new List(){"sample-child-1", "sample-child-2"} +}); + +treeNodes.Add("sample-child-1", new TreeNode() +{ + Id = "sample-child-1", + Data = new TreeData() + { + Name = "Sample Child 1" + }, + HasChildren = false, + Children = new List() {} +}); + +treeNodes.Add("sample-child-2", new TreeNode() + { + Id = "sample-child-2", + Data = new TreeData() + { + Name = "Sample Child 2" + }, + HasChildren = false, + Children = new List() { } + }); + + +tree.TreeModel = treeNodes; +``` + ## Upload ```html diff --git a/SiemensIXBlazor/Components/Tree/Tree.razor b/SiemensIXBlazor/Components/Tree/Tree.razor new file mode 100644 index 0000000..fb46dd0 --- /dev/null +++ b/SiemensIXBlazor/Components/Tree/Tree.razor @@ -0,0 +1,10 @@ +@using Microsoft.JSInterop; +@inject IJSRuntime JSRuntime +@inherits IXBaseComponent + + diff --git a/SiemensIXBlazor/Components/Tree/Tree.razor.cs b/SiemensIXBlazor/Components/Tree/Tree.razor.cs new file mode 100644 index 0000000..009fd6e --- /dev/null +++ b/SiemensIXBlazor/Components/Tree/Tree.razor.cs @@ -0,0 +1,110 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using Newtonsoft.Json; +using SiemensIXBlazor.Interops; +using SiemensIXBlazor.Objects; +using System.Dynamic; +using System.Text.Json; + +namespace SiemensIXBlazor.Components.Tree +{ + public partial class Tree + { + private Dictionary? _treeModel; + private Dictionary? _treeContext; + private Lazy>? moduleTask; + private BaseInterop? _interop; + + [Parameter, EditorRequired] + public string Id { get; set; } = string.Empty; + public Dictionary? TreeModel + { + get => _treeModel; + set + { + _treeModel = value; + InitialParameter("setTreeModel", _treeModel); + } + } + public Dictionary? TreeContext + { + get => _treeContext; + set + { + _treeContext = value; + InitialParameter("setTreeContext", _treeContext); + } + } + [Parameter] + public string? Root { get; set; } + [Parameter] + public EventCallback> ContextChangedEvent { get; set; } + [Parameter] + public EventCallback NodeRemovedEvent { get; set; } + [Parameter] + public EventCallback NodeClickedEvent { get; set; } + [Parameter] + public EventCallback NodeToggledEvent { get; set; } + + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + _interop = new(JSRuntime); + + Task.Run(async () => + { + await _interop.AddEventListener(this, Id, "contextChange", "ContextChanged"); + await _interop.AddEventListener(this, Id, "nodeRemoved", "NodeRemoved"); + await _interop.AddEventListener(this, Id, "nodeClicked", "NodeClicked"); + await _interop.AddEventListener(this, Id, "nodeToggled", "NodeToggled"); + }); + } + } + + private void InitialParameter(string functionName, object param) + { + + moduleTask = new(() => JSRuntime.InvokeAsync( + "import", $"./_content/SiemensIXBlazor/js/interops/treeInterop.js").AsTask()); + + Task.Run(async () => + { + var module = await moduleTask.Value; + if (module != null) + { + var serObj = JsonConvert.SerializeObject(param); + await module.InvokeVoidAsync(functionName, Id, JsonConvert.SerializeObject(param)); + } + }); + } + + [JSInvokable] + public async Task ContextChanged(JsonElement context) + { + string jsonDataText = context.GetRawText(); + Dictionary? changedContext = JsonConvert.DeserializeObject>(jsonDataText); + await ContextChangedEvent.InvokeAsync(changedContext); + } + + [JSInvokable] + public async Task NodeRemoved() + { + await NodeRemovedEvent.InvokeAsync(); + } + + [JSInvokable] + public async Task NodeClicked(string label) + { + await NodeClickedEvent.InvokeAsync(label); + } + + [JSInvokable] + public async Task NodeToggled(JsonElement toggledNode) + { + string jsonDataText = toggledNode.GetRawText(); + TreeNodeToggledEventResult result = JsonConvert.DeserializeObject(jsonDataText); + await NodeToggledEvent.InvokeAsync(result); + } + } +} diff --git a/SiemensIXBlazor/Objects/TreeContextNode.cs b/SiemensIXBlazor/Objects/TreeContextNode.cs new file mode 100644 index 0000000..3bf8c67 --- /dev/null +++ b/SiemensIXBlazor/Objects/TreeContextNode.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace SiemensIXBlazor.Objects +{ + public class TreeContextNode + { + [JsonProperty("isExpanded")] + public bool IsExpanded { get; set; } + [JsonProperty("isSelected")] + public bool IsSelected { get; set; } + } +} diff --git a/SiemensIXBlazor/Objects/TreeData.cs b/SiemensIXBlazor/Objects/TreeData.cs new file mode 100644 index 0000000..f6b03de --- /dev/null +++ b/SiemensIXBlazor/Objects/TreeData.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace SiemensIXBlazor.Objects +{ + public class TreeData + { + [JsonProperty("name")] + public string? Name { get; set; } + } +} diff --git a/SiemensIXBlazor/Objects/TreeNode.cs b/SiemensIXBlazor/Objects/TreeNode.cs new file mode 100644 index 0000000..6de820e --- /dev/null +++ b/SiemensIXBlazor/Objects/TreeNode.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace SiemensIXBlazor.Objects +{ + public class TreeNode + { + [JsonProperty("id")] + public string? Id { get; set; } + [JsonProperty("data")] + public TreeData? Data { get; set; } + [JsonProperty("hasChildren")] + public bool HasChildren { get; set; } + [JsonProperty("children")] + public List? Children { get; set; } + } +} diff --git a/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs b/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs new file mode 100644 index 0000000..687af66 --- /dev/null +++ b/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace SiemensIXBlazor.Objects +{ + public class TreeNodeToggledEventResult + { + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("isExpaned")] + public bool IsExpaned { get; set; } + } +} diff --git a/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js b/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js new file mode 100644 index 0000000..e81cd14 --- /dev/null +++ b/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js @@ -0,0 +1,20 @@ +export function setTreeModel(id, treeModel) { + try { + const element = document.getElementById(id); + element.model = JSON.parse(treeModel); + console.log(element, JSON.parse(treeModel)); + } + catch { + + } +} + +export function setTreeContext(id, treeContext) { + try { + const element = document.getElementById(id); + element.context = JSON.parse(treeContext); + } + catch { + + } +} \ No newline at end of file