Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
734 changes: 734 additions & 0 deletions Apps/Frameworks/AGENTS.md

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Apps/Frameworks/AntDesign/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
dist/
*.tsbuildinfo
playwright-report/
test-results/
5 changes: 5 additions & 0 deletions Apps/Frameworks/AntDesign/.universal/publishedFolders.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$assetPath = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\dist'))

if (Test-Path -LiteralPath $assetPath) {
New-PSUPublishedFolder -Name 'AntDesign Dashboard Framework' -RequestPath '/frameworks/ant-design' -Path $assetPath -DefaultDocument @('index.html')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@{
RootModule = 'Devolutions.PowerShellUniversal.Frameworks.AntDesign.psm1'
ModuleVersion = '0.1.0'
GUID = '458668d8-d3f4-4f68-bdc5-4f24836b4bd5'
Author = 'Devolutions, Inc.'
CompanyName = 'Devolutions, Inc.'
Copyright = '(c) Devolutions, Inc. All rights reserved.'
Description = 'Ant Design dashboard framework scaffold for PowerShell Universal.'
FunctionsToExport = @(
'Get-PSUAntDesignFrameworkAssetBasePath',
'Get-PSUAntDesignFrameworkEntryPoint',
'New-UDAntDesignText',
'New-UDAntDesignButton',
'New-UDAntDesignCheckbox',
'New-UDAntDesignCol',
'New-UDAntDesignInput',
'New-UDAntDesignLayout',
'New-UDAntDesignLayoutContent',
'New-UDAntDesignLayoutFooter',
'New-UDAntDesignLayoutHeader',
'New-UDAntDesignLayoutSider',
'New-UDAntDesignRate',
'New-UDAntDesignRow',
'New-UDAntDesignSwitch',
'New-UDAntDesignTypography',
'Show-AntDesignMessage',
'New-AntDesignDemo',
'New-AntDesignDemoApp'
)
PrivateData = @{
PSData = @{
Tags = @('PowerShellUniversal', 'framework', 'app', 'dashboard', 'antd')
LicenseUri = 'https://github.com/devolutions/powershell-universal-gallery/blob/main/LICENSE'
ProjectUri = 'https://github.com/devolutions/powershell-universal-gallery/tree/main/Apps/Frameworks/AntDesign'
IconUri = 'https://raw.githubusercontent.com/devolutions/powershell-universal-gallery/main/images/app.png'
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
$privatePath = Join-Path -Path $PSScriptRoot -ChildPath 'Private'
$publicPath = Join-Path -Path $PSScriptRoot -ChildPath 'Public'

if (Test-Path -Path $privatePath) {
Get-ChildItem -Path $privatePath -Filter '*.ps1' -File |
Sort-Object -Property Name |
ForEach-Object {
. $_.FullName
}
}

if (Test-Path -Path $publicPath) {
Get-ChildItem -Path $publicPath -Filter '*.ps1' -File |
Sort-Object -Property Name |
ForEach-Object {
. $_.FullName
}
}

Export-ModuleMember -Function @(
'Get-PSUAntDesignFrameworkAssetBasePath',
'Get-PSUAntDesignFrameworkEntryPoint',
'New-UDAntDesignText',
'New-UDAntDesignButton',
'New-UDAntDesignCheckbox',
'New-UDAntDesignCol',
'New-UDAntDesignInput',
'New-UDAntDesignLayout',
'New-UDAntDesignLayoutContent',
'New-UDAntDesignLayoutFooter',
'New-UDAntDesignLayoutHeader',
'New-UDAntDesignLayoutSider',
'New-UDAntDesignRate',
'New-UDAntDesignRow',
'New-UDAntDesignSwitch',
'New-UDAntDesignTypography',
'Show-AntDesignMessage',
'New-AntDesignDemo',
'New-AntDesignDemoApp'
)
302 changes: 302 additions & 0 deletions Apps/Frameworks/AntDesign/Private/Documentation.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
function Get-AntDesignHelpBlock {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$CommandName
)

$command = Get-Command -Name $CommandName -ErrorAction Stop
$commandSourcePath = $command.ScriptBlock.Ast.Extent.File

if ([string]::IsNullOrWhiteSpace($commandSourcePath)) {
throw "Unable to locate source file for $CommandName."
}

if (-not $script:AntDesignModuleSourceByPath) {
$script:AntDesignModuleSourceByPath = @{}
}

if (-not $script:AntDesignModuleSourceByPath.ContainsKey($commandSourcePath)) {
$script:AntDesignModuleSourceByPath[$commandSourcePath] = Get-Content -Path $commandSourcePath -Raw
}

$pattern = "(?ms)function\s+$([regex]::Escape($CommandName))\s*\{\s*<#(?<help>.*?)#>"
$match = [regex]::Match($script:AntDesignModuleSourceByPath[$commandSourcePath], $pattern)

if (-not $match.Success) {
throw "Unable to locate comment-based help for $CommandName."
}

$match.Groups['help'].Value
}

function ConvertFrom-AntDesignExampleBlock {
[CmdletBinding()]
param(
[string[]]$Lines,
[int]$Index
)

$content = [System.Collections.Generic.List[string]]::new()

foreach ($line in $Lines) {
$content.Add($line.TrimEnd())
}

while ($content.Count -gt 0 -and [string]::IsNullOrWhiteSpace($content[0])) {
$content.RemoveAt(0)
}

while ($content.Count -gt 0 -and [string]::IsNullOrWhiteSpace($content[$content.Count - 1])) {
$content.RemoveAt($content.Count - 1)
}

$title = "Example $Index"

if ($content.Count -gt 0 -and $content[0] -match '^#\s*(.+)$') {
$title = $Matches[1].Trim()
$content.RemoveAt(0)
}

$splitIndex = -1

for ($lineIndex = 0; $lineIndex -lt $content.Count; $lineIndex++) {
if ([string]::IsNullOrWhiteSpace($content[$lineIndex])) {
$splitIndex = $lineIndex
break
}
}

if ($splitIndex -ge 0) {
$codeLines = @($content.GetRange(0, $splitIndex))
$descriptionLines = @($content.GetRange($splitIndex + 1, $content.Count - $splitIndex - 1))
}
else {
$codeLines = @($content)
$descriptionLines = @()
}

[ordered]@{
title = $title
code = ($codeLines -join [Environment]::NewLine).Trim()
description = ($descriptionLines -join ' ').Trim()
}
}

function ConvertFrom-AntDesignHelpList {
[CmdletBinding()]
param(
[string]$Text
)

if ([string]::IsNullOrWhiteSpace($Text)) {
return @()
}

@(
$Text -split "`r?`n" |
ForEach-Object { $_.Trim() } |
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
ForEach-Object { $_ -replace '^[\-\*\u2022]\s*', '' }
)
}

function ConvertFrom-AntDesignHelpBlock {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$CommandName
)

$helpBlock = Get-AntDesignHelpBlock -CommandName $CommandName
$lines = @($helpBlock -split "`r?`n" | ForEach-Object { $_.TrimEnd() })

$result = [ordered]@{
Synopsis = ''
Description = ''
Notes = ''
Parameters = @{}
Examples = @()
}

$currentSection = $null
$currentName = $null
$buffer = [System.Collections.Generic.List[string]]::new()

function Save-AntDesignHelpSection {
param(
[string]$Section,
[string]$Name,
[System.Collections.Generic.List[string]]$SectionBuffer
)

if ([string]::IsNullOrWhiteSpace($Section)) {
return
}

$value = ($SectionBuffer.ToArray() -join [Environment]::NewLine).Trim()

if ([string]::IsNullOrWhiteSpace($value)) {
return
}

switch ($Section) {
'Synopsis' {
$result['Synopsis'] = $value
}
'Description' {
$result['Description'] = $value
}
'Notes' {
$result['Notes'] = $value
}
'Parameter' {
$result.Parameters[$Name] = ($SectionBuffer.ToArray() -join ' ').Trim()
}
'Example' {
$result['Examples'] += ,(ConvertFrom-AntDesignExampleBlock -Lines $SectionBuffer.ToArray() -Index ($result['Examples'].Count + 1))
}
}
}

foreach ($line in ($lines + '.END')) {
$trimmedLine = $line.TrimStart()

if ($trimmedLine -match '^\.(\w+)(?:\s+(.+))?$') {
Save-AntDesignHelpSection -Section $currentSection -Name $currentName -SectionBuffer $buffer
$buffer.Clear()

switch ($Matches[1].ToUpperInvariant()) {
'SYNOPSIS' {
$currentSection = 'Synopsis'
$currentName = $null
}
'DESCRIPTION' {
$currentSection = 'Description'
$currentName = $null
}
'NOTES' {
$currentSection = 'Notes'
$currentName = $null
}
'PARAMETER' {
$currentSection = 'Parameter'
$currentName = $Matches[2]
}
'EXAMPLE' {
$currentSection = 'Example'
$currentName = $null
}
Default {
$currentSection = $null
$currentName = $null
}
}

continue
}

$buffer.Add($trimmedLine)
}

$result
}

function Invoke-AntDesignDocumentationExample {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Code
)

if ([string]::IsNullOrWhiteSpace($Code)) {
return $null
}

try {
& ([scriptblock]::Create($Code))
}
catch {
New-UDAntDesignText -Text "Example preview failed: $($_.Exception.Message)"
}
}

function Get-AntDesignCommandParameters {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$CommandName,
[hashtable]$HelpParameters = @{}
)

$commonParameters = @(
'Verbose',
'Debug',
'ErrorAction',
'WarningAction',
'InformationAction',
'ProgressAction',
'ErrorVariable',
'WarningVariable',
'InformationVariable',
'OutVariable',
'OutBuffer',
'PipelineVariable'
)

$command = Get-Command -Name $CommandName -ErrorAction Stop

foreach ($parameter in $command.Parameters.Values) {
if ($parameter.Name -in $commonParameters) {
continue
}

$parameterAttribute = $parameter.Attributes | Where-Object { $_ -is [System.Management.Automation.ParameterAttribute] } | Select-Object -First 1
$validateSetAttribute = $parameter.Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] } | Select-Object -First 1

[ordered]@{
name = $parameter.Name
type = $parameter.ParameterType.Name
required = [bool]($null -ne $parameterAttribute -and $parameterAttribute.Mandatory)
description = $HelpParameters[$parameter.Name]
validValues = if ($null -ne $validateSetAttribute) { @($validateSetAttribute.ValidValues) } else { @() }
}
}
}

function Get-AntDesignComponentDocumentation {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Key,
[Parameter(Mandatory)]
[string]$Title,
[Parameter(Mandatory)]
[string]$CommandName,
[string]$Category = 'General',
[string]$SourceUrl
)

$help = ConvertFrom-AntDesignHelpBlock -CommandName $CommandName
$examples = foreach ($example in $help.Examples) {
[ordered]@{
title = $example.title
description = $example.description
code = $example.code
preview = Invoke-AntDesignDocumentationExample -Code $example.code
}
}

[ordered]@{
key = $Key
title = $Title
category = $Category
commandName = $CommandName
summary = $help.Synopsis
description = $help.Description
whenToUse = @(ConvertFrom-AntDesignHelpList -Text $help.Notes)
sourceUrl = $SourceUrl
parameters = @(Get-AntDesignCommandParameters -CommandName $CommandName -HelpParameters $help.Parameters)
examples = @($examples)
}
}
Loading