Modules/UniversalDashboard.Designer/UniversalDashboard.Designer.psm1
$IndexJs = Get-ChildItem "$PSScriptRoot\index.*.bundle.js" $DesignerAssetId = [UniversalDashboard.Services.AssetService]::Instance.RegisterScript($IndexJs.FullName) Get-ChildItem "$PSScriptRoot\*.bundle.js" | ForEach-Object { [UniversalDashboard.Services.AssetService]::Instance.RegisterScript($_.FullName) } function Start-UDPageDesigner { param( [Parameter()] $Port = 80, [Parameter()] [Switch]$Wait ) End { $EndpointInitialization = New-UDEndpointInitialization -Variable @('DesignerAssetId') -Function @("Update-UDLayout", "Add-UDDesignElement", "New-ControlProperties", "Import-UDDesignerPage", 'New-UDDesignerSurface', 'Remove-UDDesignElement', "New-UDMUInput") $Categories = @( @{ name = "General" components = @( @{ Icon = "puzzle_piece"; Name = "Element"; Component = "New-UDElement" } @{ Icon = "code"; Name = "HTML"; Component = "New-UDHtml" } ) } @{ name = "Materialize" components = @( @{ Icon = "square"; Name = "Button"; Component = "New-UDButton" } @{ Icon = "window_maximize"; Name = "Card"; Component = "New-UDCard" } @{ Icon = "check_square_o"; Name = "Checkbox"; Component = "New-UDCheckbox" } @{ Icon = "th"; Name = "Grid"; Component = "New-UDGrid" } @{ Icon = "header"; Name = "Header"; Component = "New-UDHeading" } @{ Icon = "fighter_jet"; Name = "Icon"; Component = "New-UDIcon" } @{ Icon = "window_restore"; Name = "IFrame"; Component = "New-UDIFrame" } @{ Icon = "file_picture_o"; Name = "Image"; Component = "New-UDImage" } @{ Icon = "file_text_o"; Name = "Paragraph"; Component = "New-UDParagraph" } @{ Icon = "spinner"; Name = "Preloader"; Component = "New-UDPreloader" } @{ Icon = "circle_o"; Name = "Radio"; Component = "New-UDRadio" } @{ Icon = "plus_square_o"; Name = "Select"; Component = "New-UDSelect" } @{ Icon = "toggle_on"; Name = "Switch"; Component = "New-UDSwitch" } @{ Icon = "table"; Name = "Table"; Component = "New-UDTable" } @{ Icon = "text_height"; Name = "Textbox"; Component = "New-UDTextbox" } ) } @{ name = "Material UI" components = @( @{ Icon = "user_circle"; Name = "Avatar"; Component = "New-UDMuAvatar" } @{ Icon = "square"; Name = "Button"; Component = "New-UDMuButton" } @{ Icon = "window_maximize"; Name = "Card"; Component = "New-UDMuCard" } @{ Icon = "circle"; Name = "Chip"; Component = "New-UDMuChip" } @{ Icon = "square_o"; Name = "Paper"; Component = "New-UDMuPaper" } @{ Icon = "italic"; Name = "Typography"; Component = "New-UDMuTypography" } ) } @{ name = "ChartJS" components = @( @{ Icon = "bar_chart"; Name = "Chart"; Component = "New-UDChart" } @{ Icon = "line_chart"; Name = "Monitor"; Component = "New-UDMonitor" } ) } @{ name = "Nivo" components = @( @{ Icon = "bar_chart"; Name = "Chart"; Component = "New-UDNivoChart" } ) } ) $db = New-UDDashboard -Title "Page Designer" -EndpointInitialization $EndpointInitialization -Content { New-UDElement -Tag div -Id "container" -Endpoint { $Page = Import-UDDesignerPage New-UDDesignerSurface -Id 'grid' -Categories $Categories -LayoutJson $Page.LayoutJson -Code $Session:PageContent -Content { Invoke-Expression $Page.Controls } -OnLayoutChanged { Update-UDLayout -Layout $EventData } -OnDeleteElement { Remove-UDDesignElement -Id $EventData } -OnClear { $Session:PageContent = "`$Layout = '[]' New-UDPage -Name 'Test' -Content { New-UDGridLayout -LayoutJson `$Layout -Content { } }" Set-UDElement -Id 'grid' -Attributes @{ code = $Session:PageContent } } -OnAddComponent { param($Component) New-ControlProperties -ControlName $Component } } } Start-UDDashboard -Dashboard $db -Port $Port -Wait:$Wait } } function Import-UDDesignerPage { param( ) End { if ($Session:PageContent -eq $null) { $Session:PageContent = "`$Layout = '[]' New-UDPage -Name 'Test' -Content { New-UDGridLayout -LayoutJson `$Layout -Content { } }" } $PageContent = $Session:PageContent $ScriptBlock = [ScriptBlock]::Create($PageContent) $LayoutAssignment = $ScriptBlock.Ast.Find({$args[0] -is [System.Management.Automation.Language.AssignmentStatementAst] -and $args[0].Left.ToString() -eq '$Layout'}, $true) $LayoutJson = $LayoutAssignment.Right.ToString().Trim("'") $CommandAst = $ScriptBlock.Ast.Find({$args[0] -is [System.Management.Automation.Language.CommandAst] -and $args[0].GetCommandName() -eq 'New-UDGridLayout'}, $true) $ContentScriptBlock = $CommandAst.CommandElements | Where-Object { $_ -is [System.Management.Automation.Language.ScriptBlockExpressionAst] } @{ LayoutJson = $LayoutJson Controls = $ContentScriptBlock.ScriptBlock.EndBlock.ToString() } } } function Update-UDLayout { param( [string]$Layout ) $PageContent = $Session:PageContent $ScriptBlock = [ScriptBlock]::Create($PageContent) $LayoutAssignment = $ScriptBlock.Ast.Find({$args[0] -is [System.Management.Automation.Language.AssignmentStatementAst] -and $args[0].Left.ToString() -eq '$Layout'}, $true) $PageContent = $PageContent.Remove($LayoutAssignment.Right.Extent.StartOffset, $LayoutAssignment.Right.Extent.EndOffset - $LayoutAssignment.Right.Extent.StartOffset) $PageContent = $PageContent.Insert($LayoutAssignment.Right.Extent.StartOffset, "'$Layout'") $Session:PageContent = $PageContent.TrimEnd() Set-UDElement -Id 'grid' -Attributes @{ code = $PageContent } } function Remove-UDDesignElement { param( [string]$Id ) $PageContent = $Session:PageContent $ScriptBlock = [ScriptBlock]::Create($PageContent) $CommandAst = $ScriptBlock.Ast.Find({$args[0] -is [System.Management.Automation.Language.CommandAst] -and $args[0].GetCommandName() -eq 'New-UDGridLayout'}, $true) $ContentScriptBlock = $CommandAst.CommandElements | Where-Object { $_ -is [System.Management.Automation.Language.ScriptBlockExpressionAst] } $Statement = $null $ContentScriptBlock.ScriptBlock.EndBlock.Statements | ForEach-Object { $CommandElements = $_.PipelineElements.CommandElements for($i = 0; $i -lt $CommandElements.Length; $i++) { if ($CommandElements[$i].ParameterName -eq 'Id') { if ($CommandElements[$i+1].Value -eq $id) { $Statement = $_ break } } } } if ($Statement -ne $null) { $SBString = $ScriptBlock.ToString() $SBString = $SBString.Remove($Statement.Extent.StartOffset, $Statement.Extent.EndOffset - $Statement.Extent.StartOffset) $Session:PageContent = $SBString.TrimEnd() Set-UDElement -Id 'grid' -Attributes @{ code = $PageContent } } } function Add-UDDesignElement { param( [string]$Element ) $PageContent = $Session:PageContent $ScriptBlock = [ScriptBlock]::Create($PageContent) $CommandAst = $ScriptBlock.Ast.Find({$args[0] -is [System.Management.Automation.Language.CommandAst] -and $args[0].GetCommandName() -eq 'New-UDGridLayout'}, $true) $ContentScriptBlock = $CommandAst.CommandElements | Where-Object { $_ -is [System.Management.Automation.Language.ScriptBlockExpressionAst] } $LastBracket = $ContentScriptBlock.Extent.EndOffset - 1 $PageContent = $PageContent.Insert($LastBracket, "`t" + $Element + [System.Environment]::NewLine + "`t") $Session:PageContent = $PageContent.TrimEnd() Set-UDElement -Id 'grid' -Attributes @{ code = $PageContent } } function New-ControlProperties { param( $ControlName ) $CommandInfo = Get-Command $ControlName New-UDTabContainer -Tabs { foreach($parameterSet in $CommandInfo.ParameterSets.GetEnumerator()) { New-UDTab -Text $parameterSet.Name -Content { $Properties = @() $CommonParameters = @("Verbose", "Debug", "ErrorAction", "WarningAction", "InformationAction", "ErrorVariable", "WarningVariable", "InformationVariable", "OutVariable", "OutBuffer", "PipelineVariable") foreach($parameter in ($parameterSet.Parameters | Sort-Object -Property Name)) { if ($CommonParameters -contains $parameter.Name) { continue } $Attribute = $Parameter.Attributes | Where-Object ParameterSetName -eq $parameterSet.Name if ($null -eq $Attribute) { $Attribute = $Parameter.Attributes | Where-Object ParameterSetName -eq '__AllParameterSets' } $type = "" if ($Parameter.ParameterType -eq [System.Management.Automation.SwitchParameter]) { $type = "checkbox" } elseif ($Parameter.ParameterType -eq [UniversalDashboard.Models.DashboardColor]) { $type = "color" } elseif ($Parameter.ParameterType -eq [ScriptBlock] -or $Parameter.Name -eq 'Endpoint') { $type = "code" } else { $type = "textbox" } $Properties += @{ type = $type name = $parameter.Name id = $parameter.Name set = $false mandatory = $Attribute.Mandatory } } New-UDMuInput -Properties $Properties -Endpoint { $props = $EventData | ConvertFrom-Json $arguments = @{} $IdSet = $false foreach($parameter in ($props | Where-Object {$_.Set})) { if ($parameter.Value -ne $null) { $value = $parameter.Value if ($Value -is [string] -and $Value.Contains(",")) { $value = $Value.Split(",") } if ($Parameter.Type -eq 'Code') { $Value = [ScriptBlock]::Create($Value) } $arguments[$parameter.Name] = $Value if ($Parameter.Name -eq 'Id') { $IdSet = $true } } } if (-not $IdSet) { $arguments["Id"] = (New-Guid).ToString() } Add-UDElement -ParentId "grid" -Content { . $ArgumentList[0] @arguments } $argumentString = "" foreach($parameter in ($props | Where-Object {$_.Set})) { $name = $parameter.Name $value = $arguments[$name] if ($parameter.Type -eq 'Checkbox') { $argumentString += " -$($name):`$$value" } elseif ($parameter.Type -eq 'Code') { $argumentString += " -$name {$value}" } else { $argumentString += " -$Name `"$value`"" } } if (-not $IdSet) { $argumentString += " -Id `"$($arguments["Id"])`"" } $CommandString = "$($ArgumentList[0])$argumentString" Add-UDDesignElement -Element $CommandString | Out-Null } -ArgumentList @($ControlName, $parameterSet.Name) } } } } function New-UDMUInput { param( [Hashtable[]]$Properties, [Object]$Endpoint, [object[]]$ArgumentList ) End { if ($null -ne $Endpoint -and $Endpoint -is ([ScriptBlock])) { $Endpoint = New-UDEndpoint -Endpoint $Endpoint -ArgumentList $ArgumentList } elseif ($null -ne $Endpoint -and $Endpoint -isnot ([UniversalDashboard.Models.Endpoint])) { throw "Endpoint must be a ScriptBlock of UDEndpoint" } @{ type = "muudinput" isPlugin = $true assetId = $DesignerAssetId properties = $Properties endpoint = $Endpoint.Name } } } function New-UDDesignerSurface { param( [Parameter()] [string]$Id = (New-Guid).ToString(), [Parameter()] [int]$RowHeight = 30, [Parameter()] [scriptblock]$Content, [Parameter()] [Hashtable[]]$Layout, [Parameter()] [string]$LayoutJson, [Parameter()] [int]$LargeColumns = 12, [Parameter()] [int]$MediumColumns = 10, [Parameter()] [int]$SmallColumns = 6, [Parameter()] [int]$ExtraSmallColumns = 4, [Parameter()] [int]$ExtraExtraSmallColumns = 2, [Parameter()] [int]$LargeBreakpoint = 1200, [Parameter()] [int]$MediumBreakpoint = 996, [Parameter()] [int]$SmallBreakpoint = 768, [Parameter()] [int]$ExtraSmallBreakpoint = 480, [Parameter()] [int]$ExtraExtraSmallBreakpoint = 0, [Parameter()] [switch]$Draggable, [Parameter()] [switch]$Resizable, [Parameter()] [switch]$Persist, [Parameter()] [object]$OnLayoutChanged, [Parameter()] [object]$OnDeleteElement, [Parameter()] [object]$OnAddComponent, [Parameter()] [object]$OnClear, [Parameter()] [string]$Code, [Parameter()] $Categories ) End { $Breakpoints = @{ lg = $LargeBreakpoint md = $MediumBreakpoint sm = $SmallBreakpoint xs = $ExtraSmallBreakpoint xxs = $ExtraExtraSmallBreakpoint } $Columns = @{ lg = $LargeColumns md = $MediumColumns sm = $SmallColumns xs = $ExtraSmallColumns xxs = $ExtraExtraSmallColumns } if ($null -ne $OnLayoutChanged -and $OnLayoutChanged -is ([ScriptBlock])) { $OnLayoutChanged = New-UDEndpoint -Endpoint $OnLayoutChanged } elseif ($null -ne $OnLayoutChanged -and $OnLayoutChanged -isnot ([UniversalDashboard.Models.Endpoint])) { throw "OnLayoutChanged must be a ScriptBlock of UDEndpoint" } if ($null -ne $OnDeleteElement -and $OnDeleteElement -is ([ScriptBlock])) { $OnDeleteElement = New-UDEndpoint -Endpoint $OnDeleteElement } elseif ($null -ne $OnDeleteElement -and $OnDeleteElement -isnot ([UniversalDashboard.Models.Endpoint])) { throw "OnDeleteElement must be a ScriptBlock of UDEndpoint" } if ($null -ne $OnClear -and $OnClear -is ([ScriptBlock])) { $OnClear = New-UDEndpoint -Endpoint $OnClear } elseif ($null -ne $OnClear -and $OnClear -isnot ([UniversalDashboard.Models.Endpoint])) { throw "OnClear must be a ScriptBlock of UDEndpoint" } if ($null -ne $OnAddComponent -and $OnAddComponent -is ([ScriptBlock])) { $OnAddComponent = New-UDEndpoint -Endpoint $OnAddComponent } elseif ($null -ne $OnAddComponent -and $OnAddComponent -isnot ([UniversalDashboard.Models.Endpoint])) { throw "OnAddComponent must be a ScriptBlock of UDEndpoint" } @{ type = "designer-surface" isPlugin = $true assetId = $DesignerAssetId id = $Id className = "layout" rowHeight = $RowHeight content = $Content.Invoke() layout = $Layout layoutJson = $LayoutJson cols = $Columns breakpoints = $Breakpoints isDraggable = $Draggable.IsPresent isResizable = $Resizable.IsPresent persist = $Persist.IsPresent endpoint = $OnLayoutChanged.Name onDeleteElement = $OnDeleteElement.Name onClear = $OnClear.Name code = $Code categories = $Categories onAddComponent = $OnAddComponent.Name } } } |