Skip to content
Merged
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
7 changes: 7 additions & 0 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
`${process.env.GITHUB_WORKSPACE}/DonutChart/DonutChart`,
`${process.env.GITHUB_WORKSPACE}/Elevation/Elevation`,
`${process.env.GITHUB_WORKSPACE}/Facepile/Facepile`,
`${process.env.GITHUB_WORKSPACE}/FluentMessageBar/FluentMessageBar`,
`${process.env.GITHUB_WORKSPACE}/GaugeChart/GaugeChart`,
`${process.env.GITHUB_WORKSPACE}/HorizontalBarChart/HorizontalBarChart`,
`${process.env.GITHUB_WORKSPACE}/Icon/Icon`,
Expand Down Expand Up @@ -143,6 +144,12 @@ jobs:
npm install
npm ci

- name: Install Dependencies in FluentMessageBar
run: |
cd ./FluentMessageBar
npm install
npm ci

- name: Install Dependencies in GaugeChart
run: |
cd ./GaugeChart
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr_validate_all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
- "./DonutChart"
- "./Elevation"
- "./Facepile"
- "./FluentMessageBar"
- "./GaugeChart"
- "./HorizontalBarChart"
- "./Icon"
Expand Down
51 changes: 51 additions & 0 deletions FluentMessageBar/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"env": {
"browser": true,
"es2020": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:sonarjs/recommended"
],
"globals": {
"ComponentFramework": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react",
"@microsoft/power-apps",
"@typescript-eslint",
"sonarjs"
],
"ignorePatterns": [
"**/generated/*.ts"
],
"rules": {
"indent": [
"error",
4
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
},
"settings": {
"react": {
"version": "detect"
}
}
}
17 changes: 17 additions & 0 deletions FluentMessageBar/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules

# generated directory
**/generated

# output directory
/out

# msbuild output directories
/bin
/obj

# MSBuild Binary and Structured Log
*.binlog
47 changes: 47 additions & 0 deletions FluentMessageBar/FluentMessageBar.pcfproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PowerAppsTargetsPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps</PowerAppsTargetsPath>
</PropertyGroup>

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.props" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.props')" />

<PropertyGroup>
<Name>FluentMessageBar</Name>
<ProjectGuid>83e9e0ca-0753-45c4-893a-ed5ffca3f1f5</ProjectGuid>
<OutputPath>$(MSBuildThisFileDirectory)out\controls</OutputPath>
<PcfBuildMode>production</PcfBuildMode>
</PropertyGroup>

<PropertyGroup>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<!--Remove TargetFramework when this is available in 16.1-->
<TargetFramework>net462</TargetFramework>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.PowerApps.MSBuild.Pcf" Version="1.*" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\.gitignore" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\bin\**" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\obj\**" />
<ExcludeDirectories Include="$(OutputPath)\**" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.pcfproj" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.pcfproj.user" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.sln" />
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\node_modules\**" />
</ItemGroup>

<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)\**" Exclude="@(ExcludeDirectories)" />
</ItemGroup>

<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.targets" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.targets')" />

</Project>
8 changes: 8 additions & 0 deletions FluentMessageBar/FluentMessageBar/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# msbuild output directories
/bin
/obj

# MSBuild Binary and Structured Log
*.binlog
45 changes: 45 additions & 0 deletions FluentMessageBar/FluentMessageBar/ControlManifest.Input.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<control namespace="PowerCAT" constructor="FluentMessageBar" version="0.0.33" display-name-key="FluentMessageBar_Display_Key" description-key="FluentMessageBar_Descripition_Key" control-type="virtual">
<!-- property node identifies a specific, configurable piece of data that the control expects from CDS -->
<property name="Shape" display-name-key="Shape_Key" description-key="Defines the shape of the message bar (rounded, square, etc.)." of-type="Enum" usage="input" required="true" default-value="square">
<value name="square" display-name-key="Square" description-key="Square">square</value>
<value name="rounded" display-name-key="Rounded" description-key="Rounded">rounded</value>
</property>
<property name="Intent" display-name-key="Intent_Key" description-key="Determines the message type, such as informational, success, warning, or error." of-type="Enum" usage="input" required="true" default-value="info">
<value name="info" display-name-key="Info" description-key="Info message type">info</value>
<value name="warning" display-name-key="Warning" description-key="Warning message type">warning</value>
<value name="error" display-name-key="Error" description-key="Error message type">error</value>
<value name="success" display-name-key="Success" description-key="Success message type">success</value>
</property>
<property name="Title" display-name-key="Title_Key" description-key="The title displayed on the message bar." of-type="SingleLine.Text" usage="input" required="false" />
<property name="Body" display-name-key="Body_Key" description-key="The main content or message body." of-type="SingleLine.Text" usage="input" required="true" />
<property name="LinkText" display-name-key="LinkText_Key" description-key="link text that appears in the message bar." of-type="SingleLine.Text" usage="input" required="false" />
<property name="URL" display-name-key="URL_Key" description-key="link that appears in the message bar." of-type="SingleLine.Text" usage="input" required="false" />
<property name="AutoHeight" display-name-key="Messagebar_AutoHeight_Display_Key" description-key="Messagebar_AutoHeight_Display_Key" usage="output" of-type="Whole.None" />
<property name="HideDismiss" display-name-key="Messagebar_HideDismiss_Display_Key" of-type="TwoOptions" usage="input" required="true" default-value="false" />
<common-property name="Width" default-value="350" />
<common-property name="Height" default-value="55" pfx-default-value="Self.AutoHeight" />
<!-- -->
<data-set name="Items" display-name-key="Messagebar_Toolbar_Items_Display_Key" description-key="Messagebar_Toolbar_Items_Desc_Key" pfx-default-value="Table(&#xD;&#xA; {ItemKey: &quot;mail&quot;, ItemDisplayName: &quot;Contact&quot;, ItemIconName: &quot;Mail&quot;, ItemAppearance: &quot;&quot;, ItemIconStyle: &quot;Regular&quot;, ItemTooltip: &quot;Send mail&quot;, ItemVisible: true, ItemDisabled: false},{ItemKey: &quot;chat&quot;, ItemDisplayName: &quot;Chat&quot;, ItemIconName: &quot;Chat&quot;, ItemAppearance: &quot;&quot;, ItemIconStyle: &quot;Regular&quot;, ItemTooltip: &quot;Chat&quot;})">
<property-set name="ItemDisplayName" display-name-key="Messagebar_Toolbar_Items_ItemDisplayName" of-type="SingleLine.Text" usage="bound" required="true" />
<property-set name="ItemKey" display-name-key="Messagebar_Toolbar_Items_ItemKey" of-type="SingleLine.Text" usage="bound" required="true" />
<property-set name="ItemDisabled" display-name-key="Messagebar_Toolbar_Items_ItemDisabled" of-type="TwoOptions" usage="bound" required="false" />
<property-set name="ItemVisible" display-name-key="Messagebar_Toolbar_Items_ItemVisible" of-type="TwoOptions" usage="bound" required="false" />
<property-set name="ItemIconName" display-name-key="Messagebar_Toolbar_Items_ItemIconName" of-type="SingleLine.Text" usage="bound" required="false" />
<property-set name="ItemIconStyle" display-name-key="Messagebar_Toolbar_Items_ItemIconStyle" of-type="SingleLine.Text" usage="bound" required="false" />
<property-set name="ItemAppearance" display-name-key="Messagebar_Toolbar_Items_ItemAppearance" of-type="SingleLine.Text" usage="bound" required="false" />
<property-set name="ItemTooltip" display-name-key="Messagebar_Toolbar_Items_ItemTooltip" of-type="SingleLine.Text" usage="bound" required="false" />
</data-set>
<!-- Custom Events -->
<event name="OnDismiss" display-name-key="OnDismiss" description-key="OnDismiss_Desc" />
<common-event name="OnSelect" pfx-default-value="Switch(Self.Selected.ItemKey,/* Action for Key 'mail' */&quot;mail&quot;,Notify(&quot;Contact clicked&quot;),/* Action for 'chat' */&quot;chat&quot;,Notify(&quot;Chat clicked&quot;),/* Default action */ Notify(&quot;Unrecognized button clicked&quot;))" />
<resources>
<code path="index.ts" order="1" />
<resx path="strings/FluentMessageBar.1033.resx" version="1.0.0" />
<platform-library name="React" version="16.14.0" />
<platform-library name="Fluent" version="9.46.2" />
<css path="css/messagebar.css" order="1" />
</resources>
</control>
</manifest>
44 changes: 44 additions & 0 deletions FluentMessageBar/FluentMessageBar/ManifestConstant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export const enum ItemColumns {
DisplayName = 'ItemDisplayName',
Key = 'ItemKey',
IconName = 'ItemIconName',
IconStyle = 'ItemIconStyle',
Visible = 'ItemVisible',
Disabled = 'ItemDisabled',
Appearance = 'ItemAppearance',
Tooltip = 'ItemTooltip',
}

export const enum StringConstants {
Regular = 'Regular',
Subtle = 'subtle',
AboveHeader = 'Above header',
BelowHeader = 'Below header',
}

export const Size = {
Large: 'large',
Medium: 'medium',
Small: 'small',
};

export const Layout = {
'Icon only': 'icon',
'Text only': 'text',
'Icon before': 'before',
'Icon after': 'after',
'Icon above': 'above',
};

export const enum ManifestPropertyNames {
dataset = 'dataset',
}

export const Orientation = {
Vertical: 'vertical',
Horizontal: 'horizontal',
};

export const enum Alignment {
Alignment = 'Alignment',
}
109 changes: 109 additions & 0 deletions FluentMessageBar/FluentMessageBar/__mocks__/mock-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/* istanbul ignore file */

export class MockContext<T> implements ComponentFramework.Context<T> {
constructor(parameters: T) {
this.parameters = parameters;
this.mode = {
allocatedHeight: -1,
allocatedWidth: -1,
isControlDisabled: false,
isVisible: true,
label: '',
setControlState: jest.fn(),
setFullScreen: jest.fn(),
trackContainerResize: jest.fn(),
};
this.client = {
disableScroll: false,
getClient: jest.fn(),
getFormFactor: jest.fn(),
isOffline: jest.fn(),
isNetworkAvailable: jest.fn(),
};

// Canvas apps currently assigns a positive tab-index
// so we must use this property to assign a positive tab-index also
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(this as any).accessibility = { assignedTabIndex: 0 };
}
client: ComponentFramework.Client;
device: ComponentFramework.Device;
factory: ComponentFramework.Factory;
formatting: ComponentFramework.Formatting;
mode: ComponentFramework.Mode;
navigation: ComponentFramework.Navigation;
resources: ComponentFramework.Resources;
userSettings: ComponentFramework.UserSettings;
utils: ComponentFramework.Utility;
webAPI: ComponentFramework.WebApi;
parameters: T;
updatedProperties: string[] = [];
events: IEventBag;
}

export class MockState implements ComponentFramework.Dictionary {}

export class MockStringProperty implements ComponentFramework.PropertyTypes.StringProperty {
constructor(raw?: string | null, formatted?: string | undefined) {
this.raw = raw ?? null;
this.formatted = formatted;
}
raw: string | null;
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.StringMetadata | undefined;
error: boolean;
errorMessage: string;
formatted?: string | undefined;
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
type: string;
}

export class MockWholeNumberProperty implements ComponentFramework.PropertyTypes.WholeNumberProperty {
constructor(raw?: number | null, formatted?: string | undefined) {
this.raw = raw ?? null;
this.formatted = formatted;
}
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.WholeNumberMetadata | undefined;
raw: number | null;
error: boolean;
errorMessage: string;
formatted?: string | undefined;
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
type: string;
}

export class MockEnumProperty<T> implements ComponentFramework.PropertyTypes.EnumProperty<T> {
constructor(raw?: T, type?: string) {
if (raw) this.raw = raw;
if (type) this.type = type;
}
type: string;
raw: T;
}

export class MockTwoOptionsProperty implements ComponentFramework.PropertyTypes.TwoOptionsProperty {
constructor(raw?: boolean) {
if (raw) this.raw = raw;
}
raw: boolean;
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.TwoOptionMetadata | undefined;
error: boolean;
errorMessage: string;
formatted?: string | undefined;
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
type: string;
}

export class MockDateTimeProperty implements ComponentFramework.PropertyTypes.DateTimeProperty {
constructor(raw?: Date) {
if (raw) this.raw = raw;
}
raw: Date;
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.DateTimeMetadata | undefined;
error: boolean;
errorMessage: string;
formatted?: string | undefined;
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
type: string;
}

export declare type IEventBag = Record<string, () => void>;
Loading
Loading