Skip to content

Commit

Permalink
Support CommandComponent definitions (#735)
Browse files Browse the repository at this point in the history
  • Loading branch information
joem-msft authored Jan 28, 2025
1 parent d4906d1 commit 153809e
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 73 deletions.
114 changes: 79 additions & 35 deletions schemas/pa-yaml/v3.0/pa.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,45 +238,89 @@ definitions:
type: object
propertyNames: { $ref: "#/definitions/ComponentDefinition-name" }
additionalProperties:
type: object
required: [DefinitionType]
additionalProperties: false
properties:
DefinitionType:
enum:
- CanvasComponent
- CommandComponent
Description:
description: The description for this component definition.
type: string
AccessAppScope:
description: >
Indicates whether this component can access app level information.
Not available for components defined in a component library.
type: boolean
CustomProperties:
type: object
propertyNames:
$ref: "#/definitions/ComponentDefinition-CustomProperty-name"
additionalProperties:
$ref: "#/definitions/ComponentDefinition-CustomProperty"
Properties:
allOf:
- $ref: "#/definitions/Properties-formula-map"
- propertyNames:
examples:
- ContentLanguage
- ChildTabPriority
- EnableChildFocus
- Fill
- Height
- Width
- OnReset
Children: { $ref: "#/definitions/Children-Control-instance-sequence" }
$ref: "#/definitions/ComponentDefinition-instance"

ComponentDefinition-name:
$ref: "#/definitions/entity-name"

ComponentDefinition-instance:
type: object
required: [DefinitionType]
properties:
DefinitionType:
enum:
- CanvasComponent
- CommandComponent
Description:
description: The description for this component definition.
type: string
AllowCustomization:
description: >
Only applicable for components defined in a component library.
This keyword should always be specified for component definitions in a component library.
type: boolean
allOf:
- if:
properties:
DefinitionType: { const: "CanvasComponent" }
then:
additionalProperties: false
properties:
DefinitionType: true
Description: true
AllowCustomization: true
AccessAppScope:
description: >
Indicates whether this component can access app level information.
Only applicable for canvas components that are NOT defined in a component library.
type: boolean
CustomProperties:
type: object
propertyNames:
$ref: "#/definitions/ComponentDefinition-CustomProperty-name"
additionalProperties:
$ref: "#/definitions/ComponentDefinition-CustomProperty"
Properties:
type: object
propertyNames:
allOf:
- $ref: "#/definitions/ComponentDefinition-CustomProperty-name"
- not:
enum:
- X
- Y
- Visible
additionalProperties: { $ref: "#/definitions/pfx-formula" }
properties:
ContentLanguage: { $ref: "#/definitions/pfx-formula" }
ChildTabPriority: { $ref: "#/definitions/pfx-formula" }
EnableChildFocus: { $ref: "#/definitions/pfx-formula" }
Fill: { $ref: "#/definitions/pfx-formula" }
Height: { $ref: "#/definitions/pfx-formula" }
OnReset: { $ref: "#/definitions/pfx-formula" }
Width: { $ref: "#/definitions/pfx-formula" }
Children: { $ref: "#/definitions/Children-Control-instance-sequence" }
- if:
properties:
DefinitionType: { const: "CommandComponent" }
then:
additionalProperties: false
properties:
DefinitionType: true
Description: true
AllowCustomization: true
Properties:
type: object
additionalProperties: false
properties:
AutoSave: { $ref: "#/definitions/pfx-formula" }
DataSource: { $ref: "#/definitions/pfx-formula" }
Icon: { $ref: "#/definitions/pfx-formula" }
OnSelect: { $ref: "#/definitions/pfx-formula" }
Title: { $ref: "#/definitions/pfx-formula" }
Tooltip: { $ref: "#/definitions/pfx-formula" }
Visible: { $ref: "#/definitions/pfx-formula" }

ComponentDefinition-CustomProperty-name:
$ref: "#/definitions/entity-property-name"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public void DeserializeDuplicateControlNamesShouldFail()
[DataRow(@"_TestData/SchemaV3_0/Examples/Src/Screens/FormsScreen2.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/Examples/Src/Screens/ComponentsScreen4.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/Examples/Src/Components/MyHeaderComponent.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/Examples/Src/Components/MyComponentLibrary.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/Examples/Single-File-App.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/Examples/AmbiguousComponentNames.pa.yaml")]
[DataRow(@"_TestData/SchemaV3_0/FullSchemaUses/App.pa.yaml")]
Expand Down
16 changes: 15 additions & 1 deletion src/Persistence/PaYaml/Models/SchemaV3/ComponentDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,26 @@ public record ComponentDefinition : IPaControlInstanceContainer

public string? Description { get; init; }

public bool AccessAppScope { get; init; }
/// <summary>
/// Only applicable for components in Component Libraries.
/// </summary>
public bool? AllowCustomization { get; init; }

/// <summary>
/// Only applicable for <see cref="ComponentDefinitionType.CanvasComponent"/> that are NOT in a Component Library.
/// </summary>
public bool? AccessAppScope { get; init; }

/// <summary>
/// Only applicable for <see cref="ComponentDefinitionType.CanvasComponent"/>.
/// </summary>
public NamedObjectMapping<ComponentCustomPropertyUnion>? CustomProperties { get; init; }

public NamedObjectMapping<PFxExpressionYaml>? Properties { get; init; }

/// <summary>
/// Only applicable for <see cref="ComponentDefinitionType.CanvasComponent"/>.
/// </summary>
public NamedObjectSequence<ControlInstance>? Children { get; init; }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
ComponentDefinitions:
MyHeaderComponent:
DefinitionType: CanvasComponent
Description: A header component for all screens in this app.
AllowCustomization: false
CustomProperties:
HeaderTitle:
PropertyKind: Output
DisplayName: Full Title
Description: The full title of the header
DataType: Text
Properties:
Fill: =RGBA(141, 198, 63, 1)
Height: =50
HeaderTitle: =Concatenate(MyHeaderComponent.AppTitle, " - ", MyHeaderComponent.ScreenTitle)
Width: =640
Children:
- Label4:
Control: Label
Properties:
Text: =MyHeaderComponent.HeaderTitle
Width: =Parent.Width
Height: =Parent.Height

Increment Count_1:
DefinitionType: CommandComponent
Description: A command for incrementing the `Count` field of the item being edited.
AllowCustomization: true
Properties:
DataSource: =MyLists
Icon: =Icon.Add
OnSelect: =Patch(MyLists, Self.Selected.Item, {Count:Coalesce(Self.Selected.Item.Count, 0)+1})
Visible: =Self.Selected.State = SelectedState.Edit && CountRows(Self.Selected.AllItems) = 1
121 changes: 84 additions & 37 deletions src/schemas/pa-yaml/v3.0/pa.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ definitions:
- $ref: "#/definitions/ControlTypeId-Component"
- $ref: "#/definitions/ControlTypeId-CodeComponent"

# TODO: Imlpement a way that some controls may define a limited subset of child control types
# TODO: Implement a way that some controls may define a limited subset of child control types
# e.g. The 'Form' control's children must be of type 'TypedDataCard':
# - $ref: "#/definitions/ControlTypeId-TypedDataCard"

Expand Down Expand Up @@ -260,46 +260,93 @@ definitions:
type: object
propertyNames: { $ref: "#/definitions/ComponentDefinition-name" }
additionalProperties:
type: object
required: [DefinitionType]
additionalProperties: false
properties:
DefinitionType:
enum:
- CanvasComponent
- CommandComponent
Description:
description: The description for this component definition.
type: string
AccessAppScope:
description: >
Indicates whether this component can access app level information.
Not available for components defined in a component library.
type: boolean
CustomProperties:
type: object
propertyNames:
$ref: "#/definitions/ComponentDefinition-CustomProperty-name"
additionalProperties:
$ref: "#/definitions/ComponentDefinition-CustomProperty"
Properties:
allOf:
- $ref: "#/definitions/Properties-formula-map"
- propertyNames:
examples:
# These are the known properties for a component definition, but others may be allowed in the future, along with those defined by custom Output properties.
- ContentLanguage
- ChildTabPriority
- EnableChildFocus
- Fill
- Height
- Width
- OnReset
Children: { $ref: "#/definitions/Children-Control-instance-sequence" }
$ref: "#/definitions/ComponentDefinition-instance"

ComponentDefinition-name:
$ref: "#/definitions/entity-name"

ComponentDefinition-instance:
type: object
required: [DefinitionType]
properties:
DefinitionType:
enum:
- CanvasComponent
- CommandComponent
Description:
description: The description for this component definition.
type: string
AllowCustomization:
description: >
Only applicable for components defined in a component library.
This keyword should always be specified for component definitions in a component library.
type: boolean
allOf:
- if:
properties:
DefinitionType: { const: "CanvasComponent" }
then:
additionalProperties: false
properties:
DefinitionType: true
Description: true
AllowCustomization: true
AccessAppScope:
description: >
Indicates whether this component can access app level information.
Only applicable for canvas components that are NOT defined in a component library.
type: boolean
CustomProperties:
type: object
propertyNames:
$ref: "#/definitions/ComponentDefinition-CustomProperty-name"
additionalProperties:
$ref: "#/definitions/ComponentDefinition-CustomProperty"
Properties:
type: object
# CanvasComponents may also have additional properties coming from CustomProperties.
propertyNames:
allOf:
- $ref: "#/definitions/ComponentDefinition-CustomProperty-name"
- not:
# Don't allow properties which are only applicable on component instances
enum:
- X
- Y
- Visible
additionalProperties: { $ref: "#/definitions/pfx-formula" }
properties:
# These are the well-known properties for a CanvasComponent definition
ContentLanguage: { $ref: "#/definitions/pfx-formula" }
ChildTabPriority: { $ref: "#/definitions/pfx-formula" }
EnableChildFocus: { $ref: "#/definitions/pfx-formula" }
Fill: { $ref: "#/definitions/pfx-formula" }
Height: { $ref: "#/definitions/pfx-formula" }
OnReset: { $ref: "#/definitions/pfx-formula" }
Width: { $ref: "#/definitions/pfx-formula" }
Children: { $ref: "#/definitions/Children-Control-instance-sequence" }
- if:
properties:
DefinitionType: { const: "CommandComponent" }
then:
additionalProperties: false
properties:
DefinitionType: true
Description: true
AllowCustomization: true
Properties:
type: object
# There are no other well-known properties and CommandComponents do not support custom properties.
additionalProperties: false
properties:
AutoSave: { $ref: "#/definitions/pfx-formula" }
DataSource: { $ref: "#/definitions/pfx-formula" }
Icon: { $ref: "#/definitions/pfx-formula" }
OnSelect: { $ref: "#/definitions/pfx-formula" }
Title: { $ref: "#/definitions/pfx-formula" }
Tooltip: { $ref: "#/definitions/pfx-formula" }
Visible: { $ref: "#/definitions/pfx-formula" }

ComponentDefinition-CustomProperty-name:
$ref: "#/definitions/entity-property-name"

Expand Down

0 comments on commit 153809e

Please sign in to comment.