Skip to content

Commit c0e65ed

Browse files
Merging beta into main (#38)
* Calendar Test Added - gitignore updated * Removed Shimmer Coverage/ Updated Test Snaps * Udpated Test for Progress Indicator * fix:(Calendar) test failing due to dependency on today's date (#30) * fix: (pivot) width in custom pages (#33) chore: (pivot) npm update - stay with pcf-scripts 1.14.2 due to webpack dependency issue * fix: auto-height in custom pages (#32) fix: onchange not fired when any outputs undefined chore: npm update and test chore: spelling mistake chore: variable names should be camelCase * Facepile component added (#35) * Facepile component added * reactdom-definition * fixing typos * Update Facepile.1033.resx Adding preview tag Co-authored-by: Scott Durow <[email protected]>
1 parent 9841c04 commit c0e65ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+27799
-5471
lines changed

.github/workflows/create-release.yml

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ jobs:
4141
`${process.env.GITHUB_WORKSPACE}/ContextMenu/ContextMenu`,
4242
`${process.env.GITHUB_WORKSPACE}/DetailsList/DetailsList`,
4343
`${process.env.GITHUB_WORKSPACE}/Elevation/Elevation`,
44+
`${process.env.GITHUB_WORKSPACE}/Facepile/Facepile`,
4445
`${process.env.GITHUB_WORKSPACE}/Icon/Icon`,
4546
`${process.env.GITHUB_WORKSPACE}/KeyboardShortcuts/KeyboardShortcuts`,
4647
`${process.env.GITHUB_WORKSPACE}/Nav/Nav`,
@@ -71,6 +72,8 @@ jobs:
7172
working-directory: "./DetailsList"
7273
- run: npm ci
7374
working-directory: "./Elevation"
75+
- run: npm ci
76+
working-directory: "./Facepile"
7477
- run: npm ci
7578
working-directory: "./Icon"
7679
- run: npm ci

.github/workflows/pr_validate_all.yml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- "./ContextMenu"
2020
- "./DetailsList"
2121
- "./Elevation"
22+
- "./Facepile"
2223
- "./Icon"
2324
- "./KeyboardShortcuts"
2425
- "./Nav"

Calendar/.vscode/launch.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"name": "vscode-jest-tests",
10+
"request": "launch",
11+
"args": ["${fileBasename}", "--runInBand", "--code-coverage=false" ],
12+
"cwd": "${workspaceFolder}",
13+
"console": "integratedTerminal",
14+
"internalConsoleOptions": "neverOpen",
15+
"smartStep": true,
16+
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
17+
"skipFiles": ["node_modules/**/*.js", "<node_internals>/**/*.js", "async_hooks.js", "inspector_async_hook.js"]
18+
}
19+
]
20+
}

Calendar/.vscode/settings.json

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

Calendar/config/tests.js

+3
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ const Adapter = require('enzyme-adapter-react-16');
77
// Initialize icons.
88
initializeIcons(undefined, { disableWarnings: true });
99

10+
// Ensure the test snapshots are consistent when using today's date
11+
jest.useFakeTimers('modern').setSystemTime(new Date(2022, 8, 1, 12, 0, 0));
12+
1013
// Configure enzyme.
1114
configure({ adapter: new Adapter() });

Facepile/.eslintrc.json

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"plugin:react/recommended",
9+
"plugin:react-hooks/recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
"plugin:prettier/recommended",
12+
"prettier",
13+
"plugin:sonarjs/recommended"
14+
],
15+
"parser": "@typescript-eslint/parser",
16+
"parserOptions": {
17+
"ecmaFeatures": {
18+
"jsx": true
19+
},
20+
"ecmaVersion": 12,
21+
"sourceType": "module"
22+
},
23+
"plugins": [
24+
"react",
25+
"react-hooks",
26+
"@typescript-eslint",
27+
"prettier",
28+
"sonarjs"
29+
],
30+
"settings": {
31+
"react": {
32+
"pragma": "React",
33+
"version": "detect"
34+
}
35+
},
36+
"ignorePatterns": ["**/generated/*.ts"],
37+
"rules": {
38+
"eqeqeq": [2, "smart"],
39+
"prettier/prettier": "error",
40+
"arrow-body-style": "off",
41+
"prefer-arrow-callback": "off",
42+
"linebreak-style": [
43+
"error",
44+
"windows"
45+
],
46+
"quotes": [
47+
"error",
48+
"single"
49+
],
50+
"semi": [
51+
"error",
52+
"always"
53+
]
54+
}
55+
}

Facepile/.gitignore

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
6+
# generated directory
7+
**/generated
8+
9+
# output directory
10+
/out
11+
12+
#coverage directory
13+
/coverage
14+
15+
# msbuild output directories
16+
/bin
17+
/obj

Facepile/.prettierrc.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "all",
4+
"singleQuote": true,
5+
"printWidth": 120,
6+
"tabWidth": 4,
7+
"endOfLine":"auto"
8+
}

Facepile/Facepile.pcfproj

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<PowerAppsTargetsPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps</PowerAppsTargetsPath>
5+
</PropertyGroup>
6+
7+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
8+
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.props" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.props')" />
9+
10+
<PropertyGroup>
11+
<Name>Facepile</Name>
12+
<ProjectGuid>eb11ae1f-1080-4a88-84d3-3367b8155c39</ProjectGuid>
13+
<OutputPath>$(MSBuildThisFileDirectory)out\controls</OutputPath>
14+
<PcfBuildMode>production</PcfBuildMode>
15+
</PropertyGroup>
16+
17+
<PropertyGroup>
18+
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
19+
<!--Remove TargetFramework when this is available in 16.1-->
20+
<TargetFramework>net462</TargetFramework>
21+
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
22+
</PropertyGroup>
23+
24+
<ItemGroup>
25+
<PackageReference Include="Microsoft.PowerApps.MSBuild.Pcf" Version="1.*" />
26+
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
27+
</ItemGroup>
28+
29+
<ItemGroup>
30+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\.gitignore" />
31+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\bin\**" />
32+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\obj\**" />
33+
<ExcludeDirectories Include="$(OutputPath)\**" />
34+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.pcfproj" />
35+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.pcfproj.user" />
36+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\*.sln" />
37+
<ExcludeDirectories Include="$(MSBuildThisFileDirectory)\node_modules\**" />
38+
</ItemGroup>
39+
40+
<ItemGroup>
41+
<None Include="$(MSBuildThisFileDirectory)\**" Exclude="@(ExcludeDirectories)" />
42+
</ItemGroup>
43+
44+
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" />
45+
<Import Project="$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.targets" Condition="Exists('$(PowerAppsTargetsPath)\Microsoft.PowerApps.VisualStudio.Pcf.targets')" />
46+
47+
</Project>

Facepile/Facepile/ContextExtended.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This is undocumented - but needed since canvas apps sets non-zero tabindexes
2+
// so we must use the tabindex provided by the context for accessibility purposes
3+
export interface ContextEx {
4+
accessibility: {
5+
assignedTabIndex: number;
6+
assignedTooltip?: string;
7+
};
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest>
3+
<control namespace="PowerCAT" constructor="Facepile" version="0.0.1" display-name-key="Facepile" description-key="Facepile_Desc" control-type="virtual">
4+
<property name="AccessibilityLabel" display-name-key="AccessibilityLabel" of-type="SingleLine.Text" usage="input" required="false" />
5+
<property name="Theme" display-name-key="Theme" of-type="Multiple" usage="input" required="false" />
6+
<!-- Input Property -->
7+
<property name="MaxDisplayablePersonas" display-name-key="MaxDisplayablePersonas" of-type="Whole.None" default-value="5" usage="input" />
8+
<property name="ImageShouldFadeIn" display-name-key="ImageShouldFadeIn" of-type="TwoOptions" usage="input" />
9+
<property name="ShowAddButton" display-name-key="ShowAddButton" of-type="TwoOptions" usage="input" />
10+
<property name="OverflowButtonAriaLabel" display-name-key="OverflowButtonAriaLabel" of-type="SingleLine.Text" default-value="More users" usage="input" required="false" />
11+
<property name="AddbuttonAriaLabel" display-name-key="AddbuttonAriaLabel" of-type="SingleLine.Text" default-value="Add a new person to the Facepile" usage="input" required="false" />
12+
13+
<!-- Output Property -->
14+
<property name="EventName" display-name-key="EventName" of-type="SingleLine.Text" usage="output" />
15+
<property name="PersonaSize" display-name-key="PersonaSize" description-key="PersonaSize" usage="input" of-type="Enum" required="false">
16+
<value name="Size8" display-name-key="Size8" description-key="Size8">Size8</value>
17+
<value name="Size24" display-name-key="Size24" description-key="Size24">Size24</value>
18+
<value name="Size32" display-name-key="Size32" description-key="Size32" default="true">Size32</value>
19+
<value name="Size40" display-name-key="Size40" description-key="Size40">Size40</value>
20+
<value name="Size48" display-name-key="Size48" description-key="Size48">Size48</value>
21+
<value name="Size56" display-name-key="Size56" description-key="Size56">size56</value>
22+
</property>
23+
<property name="OverflowButtonType" display-name-key="OverflowButtonType" description-key="OverflowButtonType" usage="input" of-type="Enum" required="true">
24+
<value name="none" display-name-key="none" description-key="none">none</value>
25+
<value name="descriptive" display-name-key="descriptive" description-key="descriptive" default="true">descriptive</value>
26+
<value name="downArrow" display-name-key="downArrow" description-key="downArrow">downArrow</value>
27+
<value name="more" display-name-key="more" description-key="more">more</value>
28+
</property>
29+
30+
<!-- Dataset Property -->
31+
<data-set name="items" display-name-key="Items">
32+
<property-set name="ItemPersonaName" display-name-key="ItemPersonaName" of-type="SingleLine.Text" usage="bound" required="true" />
33+
<property-set name="ItemPersonaKey" display-name-key="ItemPersonaKey" of-type="SingleLine.Text" usage="bound" required="true" />
34+
<property-set name="ItemPersonaImage" display-name-key="ItemPersonaImage" of-type="File" usage="bound" required="false" />
35+
<property-set name="ItemPersonaImageInfo" display-name-key="ItemPersonaImageInfo" of-type="SingleLine.Text" usage="bound" required="false" />
36+
<property-set name="ItemPersonaPresence" display-name-key="ItemPersonaPresence" of-type="SingleLine.Text" usage="bound" required="false" />
37+
<property-set name="IsImage" display-name-key="IsImage" of-type="TwoOptions" usage="bound" required="false" />
38+
<property-set name="ItemPersonaClickable" display-name-key="ItemPersonaClickable" of-type="TwoOptions" usage="bound" required="false" />
39+
</data-set>
40+
41+
<!-- InputEvent : SetFocus -->
42+
<property name="InputEvent" display-name-key="InputEvent" of-type="SingleLine.Text" usage="input" />
43+
<resources>
44+
<code path="index.ts" order="1" />
45+
<resx path="strings/Facepile.1033.resx" version="1.0.0" />
46+
<platform-library name="React" version="16.8.6" />
47+
<platform-library name="Fluent" version="8.29.0" />
48+
</resources>
49+
</control>
50+
</manifest>
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
export const enum ManifestPropertyNames {
2+
dataset = 'dataset',
3+
}
4+
5+
export const enum ItemColumns {
6+
DisplayName = 'ItemPersonaName',
7+
Key = 'ItemPersonaKey',
8+
ImageUrl = 'ItemPersonaImageUrl',
9+
Image = 'ItemPersonaImage',
10+
ImageInfo = 'ItemPersonaImageInfo',
11+
Role = 'ItemPersonaRole',
12+
ImageType = 'ItemImageType',
13+
Presence = 'ItemPersonaPresence',
14+
Clickable = 'ItemPersonaClickable',
15+
IsImage = 'IsImage',
16+
}
17+
18+
export const enum InputEvents {
19+
SetFocus = 'SetFocus',
20+
}
21+
22+
export const enum InputProperties {
23+
InputEvent = 'InputEvent',
24+
SelectedKey = 'SelectedKey',
25+
}
26+
27+
export const enum OutputEvents {
28+
PersonaEvent = 'PersonaEvent',
29+
OverFlowButtonEvent = 'OverFlowButtonEvent',
30+
AddButtonEvent = 'AddButtonEvent',
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* istanbul ignore file */
2+
3+
export class MockContext<T> implements ComponentFramework.Context<T> {
4+
constructor(parameters: T) {
5+
this.parameters = parameters;
6+
this.mode = {
7+
allocatedHeight: -1,
8+
allocatedWidth: -1,
9+
isControlDisabled: false,
10+
isVisible: true,
11+
label: '',
12+
setControlState: jest.fn(),
13+
setFullScreen: jest.fn(),
14+
trackContainerResize: jest.fn(),
15+
};
16+
this.client = {
17+
disableScroll: false,
18+
getClient: jest.fn(),
19+
getFormFactor: jest.fn(),
20+
isOffline: jest.fn(),
21+
};
22+
23+
// Canvas apps currently assigns a positive tab-index
24+
// so we must use this property to assign a positive tab-index also
25+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
26+
(this as any).accessibility = { assignedTabIndex: 0 };
27+
}
28+
client: ComponentFramework.Client;
29+
device: ComponentFramework.Device;
30+
factory: ComponentFramework.Factory;
31+
formatting: ComponentFramework.Formatting;
32+
mode: ComponentFramework.Mode;
33+
navigation: ComponentFramework.Navigation;
34+
resources: ComponentFramework.Resources;
35+
userSettings: ComponentFramework.UserSettings;
36+
utils: ComponentFramework.Utility;
37+
webAPI: ComponentFramework.WebApi;
38+
parameters: T;
39+
updatedProperties: string[] = [];
40+
}
41+
42+
export class MockState implements ComponentFramework.Dictionary {}
43+
44+
export class MockStringProperty implements ComponentFramework.PropertyTypes.StringProperty {
45+
constructor(raw?: string | null, formatted?: string | undefined) {
46+
this.raw = raw ?? null;
47+
this.formatted = formatted;
48+
}
49+
raw: string | null;
50+
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.StringMetadata | undefined;
51+
error: boolean;
52+
errorMessage: string;
53+
formatted?: string | undefined;
54+
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
55+
type: string;
56+
}
57+
58+
export class MockWholeNumberProperty implements ComponentFramework.PropertyTypes.WholeNumberProperty {
59+
constructor(raw?: number | null, formatted?: string | undefined) {
60+
this.raw = raw ?? null;
61+
this.formatted = formatted;
62+
}
63+
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.WholeNumberMetadata | undefined;
64+
raw: number | null;
65+
error: boolean;
66+
errorMessage: string;
67+
formatted?: string | undefined;
68+
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
69+
type: string;
70+
}
71+
72+
export class MockEnumProperty<T> implements ComponentFramework.PropertyTypes.EnumProperty<T> {
73+
constructor(raw?: T, type?: string) {
74+
if (raw) this.raw = raw;
75+
if (type) this.type = type;
76+
}
77+
type: string;
78+
raw: T;
79+
}
80+
81+
export class MockTwoOptionsProperty implements ComponentFramework.PropertyTypes.TwoOptionsProperty {
82+
constructor(raw?: boolean) {
83+
if (raw) this.raw = raw;
84+
}
85+
raw: boolean;
86+
attributes?: ComponentFramework.PropertyHelper.FieldPropertyMetadata.TwoOptionMetadata | undefined;
87+
error: boolean;
88+
errorMessage: string;
89+
formatted?: string | undefined;
90+
security?: ComponentFramework.PropertyHelper.SecurityValues | undefined;
91+
type: string;
92+
}

0 commit comments

Comments
 (0)