├── .gitignore ├── ActionButton ├── .gitignore ├── ActionButton.pcfproj ├── ActionButton │ ├── ButtonControl.tsx │ ├── ControlManifest.Input.xml │ ├── imgs │ │ └── logo.png │ ├── index.ts │ ├── screenshots │ │ ├── screenshot.png │ │ └── screenshot2.png │ └── strings │ │ ├── ActionButton.1031.resx │ │ ├── ActionButton.1033.resx │ │ └── ActionButton.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── CustomSwitch ├── .gitignore ├── CustomSwitch.pcfproj ├── CustomSwitch │ ├── ControlManifest.Input.xml │ ├── CustomSwitchSolution │ │ ├── .gitignore │ │ ├── CustomSwitchSolution.cdsproj │ │ └── Other │ │ │ ├── Customizations.xml │ │ │ ├── Relationships.xml │ │ │ └── Solution.xml │ ├── css │ │ └── CustomSwitch.css │ ├── imgs │ │ └── preview.png │ ├── index.ts │ └── strings │ │ ├── CustomSwitch.1031.resx │ │ ├── CustomSwitch.1033.resx │ │ └── CustomSwitch.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json ├── screenshots │ └── capture.png └── tsconfig.json ├── DateAsCheckbox ├── .gitignore ├── DateAsCheckbox.pcfproj ├── DateAsCheckbox │ ├── ControlManifest.Input.xml │ ├── DateAsCheckBoxSolution │ │ ├── .gitignore │ │ ├── DateAsCheckBoxSolution.cdsproj │ │ └── src │ │ │ └── Other │ │ │ ├── Customizations.xml │ │ │ ├── Relationships.xml │ │ │ └── Solution.xml │ ├── css │ │ └── DateAsCheckbox.css │ ├── index.ts │ └── strings │ │ ├── DateAsCheckbox.1031.resx │ │ ├── DateAsCheckbox.1033.resx │ │ └── DateAsCheckbox.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json ├── screenshots │ └── dateAsCheckbox.gif └── tsconfig.json ├── DateRangePickerPCF ├── .eslintrc.json ├── .gitignore ├── DateRangePickerPCF.pcfproj ├── DateRangerPickerPCF │ ├── ControlManifest.Input.xml │ ├── CustomTheme.less │ ├── MyDateRangePicker.tsx │ ├── index.ts │ └── strings │ │ ├── DateRangePicker.1033.resx │ │ └── DateRangePicker.1036.resx ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── DateRangePickerSolution ├── Build Release-DateRangePicker.bat ├── DateRangePicker.cdsproj └── src │ └── Other │ ├── Customizations.xml │ ├── Relationships.xml │ └── Solution.xml ├── LICENSE ├── LinearSliderWithSteps ├── .gitignore ├── LinearSliderWithSteps.pcfproj ├── LinearSliderWithSteps │ ├── ControlManifest.Input.xml │ ├── css │ │ └── LinearSliderWithSteps.css │ ├── imgs │ │ └── screenshot.png │ ├── index.ts │ └── strings │ │ ├── LinearSliderWithSteps.1031.resx │ │ ├── LinearSliderWithSteps.1033.resx │ │ └── LinearSliderWithSteps.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── LookupToPicklist ├── .gitignore ├── LooklupToPicklist │ ├── ControlManifest.Input.xml │ ├── Interfaces.ts │ ├── LookupCombobox.tsx │ ├── img │ │ └── LookupToPicklist_preview.png │ ├── index.ts │ └── strings │ │ ├── LookupToPicklist.1031.resx │ │ ├── LookupToPicklist.1033.resx │ │ └── LookupToPicklist.1036.resx ├── LookupToPicklist.pcfproj ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── MscrmToolsPCFControls ├── .gitignore ├── Build Release-DateRangePicker.bat ├── Build Release.bat ├── MscrmToolsPCFControls.cdsproj └── src │ └── Other │ ├── Customizations.xml │ ├── Relationships.xml │ └── Solution.xml ├── NNCheckboxes ├── .gitignore ├── NNCheckboxes.pcfproj ├── NNCheckboxes │ ├── ControlManifest.Input.xml │ ├── Solution │ │ ├── .gitignore │ │ ├── Other │ │ │ ├── Customizations.xml │ │ │ ├── Relationships.xml │ │ │ └── Solution.xml │ │ └── Solution.cdsproj │ ├── css │ │ └── NNCheckboxes.css │ ├── imgs │ │ ├── logo.png │ │ └── nncheckboxes.png │ ├── index.ts │ ├── referential.ts │ ├── reldef.ts │ └── strings │ │ ├── NNCheckboxes.1031.resx │ │ ├── NNCheckboxes.1033.resx │ │ └── NNCheckboxes.1036.resx ├── Screenshots │ ├── ColorAndGroups.png │ ├── Configuration.png │ ├── Control.png │ ├── Sample1.png │ ├── Sample10.png │ ├── Sample2.png │ ├── Sample3.png │ ├── Sample4.png │ ├── Sample5.png │ ├── Sample6.png │ ├── Sample7.png │ ├── Sample8.png │ ├── Sample9.png │ └── video.gif ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── README.md ├── ReactNotifier ├── .gitignore ├── ReactNotifier.pcfproj ├── ReactNotifier │ ├── ControlManifest.Input.xml │ ├── NotificationControl.tsx │ ├── imgs │ │ └── ReactNotification.png │ ├── index.ts │ └── strings │ │ ├── ReactNotifier.1031.resx │ │ ├── ReactNotifier.1033.resx │ │ └── ReactNotifier.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json └── tsconfig.json ├── YearDropdown ├── .eslintrc.json ├── .gitignore ├── YearDropdown.pcfproj ├── YearDropdown │ ├── .eslintrc.json │ ├── ControlManifest.Input.xml │ ├── components │ │ ├── DropdownNew.tsx │ │ ├── DropdownOld.tsx │ │ ├── IRecordSelectorProps.ts │ │ └── RecordSelector.tsx │ ├── img │ │ └── YearDropdown.png │ ├── index.ts │ └── strings │ │ ├── YearDropdown.1031.resx │ │ ├── YearDropdown.1033.resx │ │ └── YearDropdown.1036.resx ├── eslint.config.mjs ├── package-lock.json ├── package.json ├── pcfconfig.json ├── screenshots │ └── YearDropdown.gif └── tsconfig.json └── package-lock.json /ActionButton/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj -------------------------------------------------------------------------------- /ActionButton/ActionButton.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | ActionButton 12 | bc249511-6921-4066-88f1-c66c38823a47 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ActionButton/ActionButton/ButtonControl.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Stack } from '@fluentui/react/lib/Stack'; 3 | import { IBaseButtonProps, IBaseButtonState, IButtonStyles, PrimaryButton, IconButton } from '@fluentui/react/lib/Button' 4 | import { IIconProps } from '@fluentui/react'; 5 | import { TooltipHost } from '@fluentui/react/lib/Tooltip'; 6 | 7 | export interface IButtonControlProps extends IBaseButtonProps { 8 | hoverBackgroundColor: string, 9 | hoverBorderColor: string, 10 | hoverColor: string, 11 | checkedBackgroundColor: string, 12 | checkedBorderColor: string, 13 | checkedColor: string, 14 | iconName: string | null, 15 | toolTip: string | undefined, 16 | } 17 | 18 | export default class ButtonControl extends React.Component{ 19 | constructor(props: IButtonControlProps) { 20 | super(props); 21 | } 22 | styles: IButtonStyles = { 23 | root: { 24 | backgroundColor: this.props.style?.backgroundColor ?? "#0078d4", 25 | borderColor: this.props.style?.borderColor ?? "#0078d4", 26 | color: this.props.style?.color ?? "#FFFFFF", 27 | width: this.props.style?.width 28 | }, 29 | rootHovered: { 30 | backgroundColor: this.props.hoverBackgroundColor ?? "#106EBE", 31 | borderColor: this.props.hoverBorderColor ?? "#106EBE", 32 | color: this.props.hoverColor ?? "#FFFFFF", 33 | width: this.props.style?.width 34 | }, 35 | rootPressed: { 36 | backgroundColor: this.props.checkedBackgroundColor ?? "#0078d4", 37 | borderColor: this.props.checkedBorderColor ?? "#0078d4", 38 | color: this.props.checkedColor ?? "#FFFFFF", 39 | width: this.props.style?.width 40 | } 41 | } 42 | 43 | icon: IIconProps = { iconName: this.props.iconName ?? "" }; 44 | 45 | render() { 46 | const toolTipId = `tooltip_${this.props.iconName}`; 47 | 48 | return ( 49 | 50 | {this.props.text?.trim().length ? ( 51 | 52 | 60 | 61 | ) : ( 62 | 63 | 70 | 71 | )} 72 | 73 | ); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /ActionButton/ActionButton/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 1 10 | 0 11 | 12 | 13 | 14 | 1 15 | 0 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | DateAndTime.DateAndTime 30 | DateAndTime.DateOnly 31 | SingleLine.Text 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ActionButton/ActionButton/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/ActionButton/ActionButton/imgs/logo.png -------------------------------------------------------------------------------- /ActionButton/ActionButton/screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/ActionButton/ActionButton/screenshots/screenshot.png -------------------------------------------------------------------------------- /ActionButton/ActionButton/screenshots/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/ActionButton/ActionButton/screenshots/screenshot2.png -------------------------------------------------------------------------------- /ActionButton/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import pluginReact from "eslint-plugin-react"; 5 | import { defineConfig } from "eslint/config"; 6 | 7 | 8 | export default defineConfig([ 9 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] }, 10 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], languageOptions: { globals: globals.browser } }, 11 | tseslint.configs.recommended, 12 | pluginReact.configs.flat.recommended, 13 | { 14 | 15 | rules: { 16 | "@typescript-eslint/no-unused-vars": "off", 17 | "@typescript-eslint/no-explicit-any": "off", 18 | "@typescript-eslint/no-unsafe-member-access": "off", 19 | "@typescript-eslint/no-unsafe-call": "off", 20 | "@typescript-eslint/no-misused-promises": "off", 21 | "@typescript-eslint/no-empty-object-types": "off", 22 | "@react/no-deprecated":"off" 23 | }, 24 | settings: { 25 | react: { 26 | version: "detect", 27 | }, 28 | }, 29 | } 30 | ]); -------------------------------------------------------------------------------- /ActionButton/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.25.1", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint": "^9.25.1", 29 | "eslint-plugin-promise": "^7.1.0", 30 | "eslint-plugin-react": "^7.37.5", 31 | "globals": "^15.15.0", 32 | "pcf-scripts": "^1", 33 | "pcf-start": "^1", 34 | "react": "^16.14.0", 35 | "typescript": "^4.9.5", 36 | "typescript-eslint": "^8.31.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ActionButton/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /ActionButton/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /CustomSwitch/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | CustomSwitch 12 | dd033002-92f9-4908-b921-997880747c07 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Round 10 | Square 11 | 12 | 13 | True 14 | False 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 35 | 36 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/CustomSwitchSolution/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /obj -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/CustomSwitchSolution/CustomSwitchSolution.cdsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | 765cc827-bd76-430a-9575-7c5aba18c8b1 12 | v4.6.2 13 | 14 | net462 15 | PackageReference 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/CustomSwitchSolution/Other/Customizations.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 1033 17 | 18 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/CustomSwitchSolution/Other/Relationships.xml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/CustomSwitchSolution/Other/Solution.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CustomSwitchSolution 6 | 7 | 8 | 9 | 10 | 11 | 1.0 12 | 13 | 2 14 | 15 | 16 | MscrmTools 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | mctools 29 | 30 | 54953 31 | 32 | 33 |
34 | 1 35 | 1 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 1 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 |
62 | 2 63 | 1 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 1 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 |
90 |
91 | 92 | 93 |
94 |
-------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/css/CustomSwitch.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | input[type=checkbox] + label { 6 | vertical-align: middle; 7 | position: relative; 8 | bottom: 1px; 9 | font-weight: bold; 10 | } 11 | 12 | input[type=checkbox]:checked + label{ 13 | font-weight: normal; 14 | text-decoration: line-through; 15 | } 16 | 17 | div.ccb-main{ 18 | margin-top:10px; 19 | } 20 | 21 | /* Customize the label (the container) */ 22 | .ccb-container { 23 | display: block; 24 | position: relative; 25 | top:6px; 26 | padding-bottom: 1px; 27 | margin-bottom: 12px; 28 | margin-right:10px; 29 | border-radius: 5px; 30 | cursor: pointer; 31 | -webkit-user-select: none; 32 | -moz-user-select: none; 33 | -ms-user-select: none; 34 | user-select: none; 35 | font-family: "Segoe UI",tahoma,Arial; 36 | font-size: 14px; 37 | color: #444444; 38 | text-align:left; 39 | } 40 | 41 | /* Hide the browser's default checkbox */ 42 | .ccb-container input { 43 | position: absolute; 44 | opacity: 0; 45 | cursor: pointer; 46 | } 47 | 48 | /* toggle switch */ 49 | /* The switch - the box around the slider */ 50 | .ccb-container-switch { 51 | position: relative; 52 | display: inline-block; 53 | width: 40px; 54 | height: 22px; 55 | display:inline-block; 56 | vertical-align:middle; 57 | } 58 | 59 | /* Hide default HTML checkbox */ 60 | .ccb-container-switch input { 61 | opacity: 0; 62 | width: 0; 63 | height: 0; 64 | } 65 | 66 | /* The slider */ 67 | .ccb-slider-default { 68 | position: absolute; 69 | cursor: pointer; 70 | top: 0; 71 | left: 0; 72 | right: 0; 73 | bottom: 0; 74 | background-color: #FFFFFF; 75 | -webkit-transition: .4s; 76 | transition: .4s; 77 | border:solid 2px black; 78 | } 79 | 80 | .ccb-slider-default:before { 81 | position: absolute; 82 | content: ""; 83 | height: 14px; 84 | width: 14px; 85 | left: 2px; 86 | bottom: 2px; 87 | background-color: black; 88 | -webkit-transition: .4s; 89 | transition: .4s; 90 | } 91 | 92 | input:checked + .ccb-slider-default{ 93 | background-color: #008800; 94 | border:solid 2px #008800; 95 | } 96 | 97 | input:checked + .ccb-slider-default:before{ 98 | background-color:white; 99 | -webkit-transform: translateX(18px); 100 | -ms-transform: translateX(18px); 101 | transform: translateX(18px); 102 | } 103 | 104 | /* Rounded sliders */ 105 | input:checked + .ccb-slider-default.ccb-round { 106 | border-radius: 34px; 107 | } 108 | 109 | .ccb-round { 110 | border-radius: 34px; 111 | } 112 | 113 | .ccb-slider-default.ccb-round:before{ 114 | border-radius: 50%; 115 | } 116 | 117 | span.ccb-switch-label{ 118 | padding-left:5px; 119 | display:inline-block; 120 | vertical-align:middle; 121 | } -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/imgs/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/CustomSwitch/CustomSwitch/imgs/preview.png -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/strings/CustomSwitch.1031.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Benutzerdefinierter Schalter 63 | 64 | 65 | Layout und Farben des Schalters anpassen 66 | 67 | 68 | Attribut 69 | 70 | 71 | Das anzuzeigende ZweiOptionen-Attribut 72 | 73 | 74 | Farbe bei Ein 75 | 76 | 77 | Hintergrundfarbe des Schalters, wenn der Wert Ein ist 78 | 79 | 80 | Farbe bei Aus 81 | 82 | 83 | Hintergrundfarbe des Schalters, wenn der Wert Aus ist 84 | 85 | 86 | Schalterfarbe 87 | 88 | 89 | Farbe des Schalters 90 | 91 | 92 | Layout 93 | 94 | 95 | Wählen Sie das Layout für den Schalter 96 | 97 | 98 | Rund 99 | 100 | 101 | Schalter als rund anzeigen 102 | 103 | 104 | Quadratisch 105 | 106 | 107 | Schalter als quadratisch anzeigen 108 | 109 | 110 | Beschriftung anzeigen 111 | 112 | 113 | Wählen Sie, ob das Label der ausgewählten Option neben dem Schalter angezeigt werden soll 114 | 115 | 116 | Ja 117 | 118 | 119 | Ja 120 | 121 | 122 | Nein 123 | 124 | 125 | Nein 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/strings/CustomSwitch.1033.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Custom Switch 63 | 64 | 65 | Customize layout and colors of the switch 66 | 67 | 68 | Attribute 69 | 70 | 71 | The TwoOptions attribute to display 72 | 73 | 74 | On color 75 | 76 | 77 | Background color of the switch when the value is On 78 | 79 | 80 | Off color 81 | 82 | 83 | Background color of the switch when the value is Off 84 | 85 | 86 | Switch color 87 | 88 | 89 | Color of the switch 90 | 91 | 92 | Layout 93 | 94 | 95 | Select the layout for the switch 96 | 97 | 98 | Round 99 | 100 | 101 | Display switch as rounded 102 | 103 | 104 | Square 105 | 106 | 107 | Display switch as squared 108 | 109 | 110 | 111 | Display label 112 | 113 | 114 | Select wether to display selected option label next to the switch 115 | 116 | 117 | Yes 118 | 119 | 120 | Yes 121 | 122 | 123 | No 124 | 125 | 126 | No 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /CustomSwitch/CustomSwitch/strings/CustomSwitch.1036.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Interrupteur personnalisé 63 | 64 | 65 | Personnalisez les couleurs et la mise en forme de l'interrupteur 66 | 67 | 68 | Attribut 69 | 70 | 71 | L'attribut Deux Options à afficher 72 | 73 | 74 | Couleur de l'état Activé 75 | 76 | 77 | Couleur d'arrière plan quand l'interrupteur est à l'état Activé 78 | 79 | 80 | Couleur de l'état Désctivé 81 | 82 | 83 | Couleur d'arrière plan quand l'interrupteur est à l'état Désactivé 84 | 85 | 86 | Couleur 87 | 88 | 89 | Couleur de l'interrupteur 90 | 91 | 92 | Mise en forme 93 | 94 | 95 | Sélectionner la mise en forme pour l'interrupteur 96 | 97 | 98 | Ronde 99 | 100 | 101 | Afficher l'interrupteur avec des bords rond 102 | 103 | 104 | Carrée 105 | 106 | 107 | Afficher l'interrupteur avec des bords carrés 108 | 109 | 110 | 111 | Afficher le libellé 112 | 113 | 114 | Définit si le libellé de l'option sélectionné doit être affiché à coté de l'interrupteur 115 | 116 | 117 | Oui 118 | 119 | 120 | Oui 121 | 122 | 123 | Non 124 | 125 | 126 | Non 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /CustomSwitch/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import pluginReact from "eslint-plugin-react"; 5 | import { defineConfig } from "eslint/config"; 6 | 7 | 8 | export default defineConfig([ 9 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] }, 10 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], languageOptions: { globals: globals.browser } }, 11 | tseslint.configs.recommended, 12 | pluginReact.configs.flat.recommended, 13 | ]); -------------------------------------------------------------------------------- /CustomSwitch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.25.1", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint": "^9.25.1", 29 | "eslint-plugin-promise": "^7.1.0", 30 | "eslint-plugin-react": "^7.37.5", 31 | "globals": "^15.15.0", 32 | "pcf-scripts": "^1", 33 | "pcf-start": "^1", 34 | "react": "^16.14.0", 35 | "typescript": "^4.9.5", 36 | "typescript-eslint": "^8.31.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /CustomSwitch/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /CustomSwitch/screenshots/capture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/CustomSwitch/screenshots/capture.png -------------------------------------------------------------------------------- /CustomSwitch/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /DateAsCheckbox/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | DateAsCheckbox 12 | 48b5b2e8-823f-4027-aaff-79856bd522ee 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Round 11 | Square 12 | 13 | 14 | DateAndTime.DateAndTime 15 | DateAndTime.DateOnly 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/DateAsCheckBoxSolution/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # msbuild output directories 4 | /bin 5 | /obj -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/DateAsCheckBoxSolution/DateAsCheckBoxSolution.cdsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | 07478ea6-69a2-4388-8dc3-9a7675dbce6f 12 | v4.6.2 13 | 14 | net462 15 | PackageReference 16 | src 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/DateAsCheckBoxSolution/src/Other/Customizations.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 1033 17 | 18 | -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/DateAsCheckBoxSolution/src/Other/Relationships.xml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/DateAsCheckBoxSolution/src/Other/Solution.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DateAsCheckBoxSolution 6 | 7 | 8 | 9 | 10 | 11 | 1.0 12 | 13 | 2 14 | 15 | 16 | MscrmTools 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | mctools 29 | 30 | 54953 31 | 32 | 33 |
34 | 1 35 | 1 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 1 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 |
62 | 2 63 | 1 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 1 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 |
90 |
91 | 92 | 93 |
94 |
-------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/css/DateAsCheckbox.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | input[type=checkbox] + label { 6 | vertical-align: middle; 7 | position: relative; 8 | bottom: 1px; 9 | font-weight: bold; 10 | } 11 | 12 | input[type=checkbox]:checked + label{ 13 | font-weight: normal; 14 | text-decoration: line-through; 15 | } 16 | 17 | div.dac-main{ 18 | margin-top:10px; 19 | } 20 | 21 | /* Customize the label (the container) */ 22 | .dac-container { 23 | display: block; 24 | position: relative; 25 | top:6px; 26 | padding-bottom: 1px; 27 | margin-bottom: 12px; 28 | margin-right:10px; 29 | border-radius: 5px; 30 | cursor: pointer; 31 | -webkit-user-select: none; 32 | -moz-user-select: none; 33 | -ms-user-select: none; 34 | user-select: none; 35 | font-family: "Segoe UI",tahoma,Arial; 36 | font-size: 14px; 37 | color: #444444; 38 | text-align:left; 39 | } 40 | 41 | /* Hide the browser's default checkbox */ 42 | .dac-container input { 43 | position: absolute; 44 | opacity: 0; 45 | cursor: pointer; 46 | } 47 | 48 | /* toggle switch */ 49 | /* The switch - the box around the slider */ 50 | .dac-container-switch { 51 | position: relative; 52 | display: inline-block; 53 | width: 40px; 54 | height: 22px; 55 | display:inline-block; 56 | vertical-align:middle; 57 | } 58 | 59 | /* Hide default HTML checkbox */ 60 | .dac-container-switch input { 61 | opacity: 0; 62 | width: 0; 63 | height: 0; 64 | } 65 | 66 | /* The slider */ 67 | .dac-slider-default { 68 | position: absolute; 69 | cursor: pointer; 70 | top: 0; 71 | left: 0; 72 | right: 0; 73 | bottom: 0; 74 | background-color: #FFFFFF; 75 | -webkit-transition: .4s; 76 | transition: .4s; 77 | border:solid 2px black; 78 | } 79 | 80 | .dac-slider-default:before { 81 | position: absolute; 82 | content: ""; 83 | height: 14px; 84 | width: 14px; 85 | left: 2px; 86 | bottom: 2px; 87 | background-color: black; 88 | -webkit-transition: .4s; 89 | transition: .4s; 90 | } 91 | 92 | input:checked + .dac-slider-default{ 93 | background-color: #008800; 94 | border:solid 2px #008800; 95 | } 96 | 97 | input:checked + .dac-slider-default:before{ 98 | background-color:white; 99 | -webkit-transform: translateX(18px); 100 | -ms-transform: translateX(18px); 101 | transform: translateX(18px); 102 | } 103 | 104 | /* Rounded sliders */ 105 | input:checked + .dac-slider-default.dac-round { 106 | border-radius: 34px; 107 | } 108 | 109 | .dac-round { 110 | border-radius: 34px; 111 | } 112 | 113 | .dac-slider-default.dac-round:before{ 114 | border-radius: 50%; 115 | } 116 | 117 | span.dac-switch-label{ 118 | padding-left:5px; 119 | display:inline-block; 120 | vertical-align:middle; 121 | } -------------------------------------------------------------------------------- /DateAsCheckbox/DateAsCheckbox/index.ts: -------------------------------------------------------------------------------- 1 | import {IInputs, IOutputs} from "./generated/ManifestTypes"; 2 | 3 | export class DateAsCheckbox implements ComponentFramework.StandardControl { 4 | 5 | private _checkboxid:string; 6 | private _labelid:string; 7 | private _options:Array; 8 | private _notifyOutputChanged: () => void; 9 | 10 | /** 11 | * Empty constructor. 12 | */ 13 | constructor() 14 | { 15 | 16 | } 17 | 18 | /** 19 | * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here. 20 | * Data-set values are not initialized here, use updateView. 21 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions. 22 | * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously. 23 | * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface. 24 | * @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content. 25 | */ 26 | public init(context: ComponentFramework.Context, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement) 27 | { 28 | const id = Math.random().toString().split('.')[1]; 29 | this._checkboxid = id + "-c"; 30 | this._labelid = id + "-l"; 31 | // @ts-expect-error not exposed by the framework 32 | this._options = context.parameters.DateAttribute.attributes.Options; 33 | this._notifyOutputChanged = notifyOutputChanged; 34 | 35 | const subContainer = document.createElement("div"); 36 | subContainer.className = "dac-container"; 37 | container.appendChild(subContainer); 38 | 39 | const lblContainer = document.createElement("label"); 40 | lblContainer.setAttribute("class", "dac-container-switch"); 41 | subContainer.appendChild(lblContainer); 42 | 43 | 44 | 45 | const chk = document.createElement("input"); 46 | chk.id = this._checkboxid; 47 | chk.setAttribute("type", "checkbox"); 48 | chk.addEventListener("change", this.changefunction); 49 | 50 | if (context.mode.isControlDisabled) { 51 | chk.setAttribute("disabled", "disabled"); 52 | } 53 | 54 | const toggle = document.createElement("span"); 55 | 56 | lblContainer.appendChild(chk); 57 | lblContainer.appendChild(toggle); 58 | 59 | if(context.parameters.offColor && context.parameters.offColor.raw) 60 | { 61 | this.createStyleRule(".dac-slider-" + this._checkboxid, "{background-color:"+context.parameters.offColor.raw+" !important;border:solid 2px " + context.parameters.offColor.raw + " !important;}"); 62 | } 63 | 64 | if(context.parameters.onColor && context.parameters.onColor.raw) 65 | { 66 | this.createStyleRule("input:checked + .dac-slider-" + this._checkboxid, "{background-color:"+context.parameters.onColor.raw+" !important;border:solid 2px " + context.parameters.onColor.raw + " !important;}"); 67 | } 68 | 69 | if(context.parameters.switchColor && context.parameters.switchColor.raw){ 70 | this.createStyleRule(".dac-slider-" + this._checkboxid + "::before", "{background-color:"+context.parameters.switchColor.raw+" !important;}"); 71 | } 72 | 73 | if(context.parameters.layout && context.parameters.layout.raw === "Square"){ 74 | toggle.setAttribute("class","dac-slider-default dac-slider-" + this._checkboxid); 75 | } 76 | else{ 77 | toggle.setAttribute("class","dac-slider-default dac-slider-" + this._checkboxid + " dac-round"); 78 | } 79 | } 80 | private changefunction(){ 81 | this._notifyOutputChanged(); 82 | } 83 | 84 | private createStyleRule(name:string,content:string){ 85 | const styleSheet = this.GetStyleSheet(); 86 | if(styleSheet != null){ 87 | styleSheet.insertRule(name + " " + content); 88 | } 89 | } 90 | 91 | 92 | private GetStyleSheet() { 93 | for(let i=0; i): void 109 | { 110 | if(context.parameters.DateAttribute){ 111 | (document.getElementById(this._checkboxid)).checked = context.parameters.DateAttribute.raw != null && context.parameters.DateAttribute.raw != undefined ; 112 | } 113 | } 114 | 115 | /** 116 | * It is called by the framework prior to a control receiving new data. 117 | * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output” 118 | */ 119 | public getOutputs(): IOutputs 120 | { 121 | let date : Date | undefined; 122 | date = new Date(); 123 | if((document.getElementById(this._checkboxid)).checked === false){ 124 | date = undefined; 125 | } 126 | 127 | return { 128 | DateAttribute : date 129 | }; 130 | } 131 | 132 | /** 133 | * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup. 134 | * i.e. cancelling any pending remote calls, removing listeners, etc. 135 | */ 136 | public destroy(): void 137 | { 138 | // Add code to cleanup control if necessary 139 | } 140 | } -------------------------------------------------------------------------------- /DateAsCheckbox/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import pluginReact from "eslint-plugin-react"; 5 | import { defineConfig } from "eslint/config"; 6 | 7 | 8 | export default defineConfig([ 9 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] }, 10 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], languageOptions: { globals: globals.browser } }, 11 | tseslint.configs.recommended, 12 | pluginReact.configs.flat.recommended, 13 | ]); -------------------------------------------------------------------------------- /DateAsCheckbox/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.25.1", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint": "^9.25.1", 29 | "eslint-plugin-promise": "^7.1.0", 30 | "eslint-plugin-react": "^7.37.5", 31 | "globals": "^15.15.0", 32 | "pcf-scripts": "^1", 33 | "pcf-start": "^1", 34 | "react": "^16.14.0", 35 | "typescript": "^4.9.5", 36 | "typescript-eslint": "^8.31.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DateAsCheckbox/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /DateAsCheckbox/screenshots/dateAsCheckbox.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/DateAsCheckbox/screenshots/dateAsCheckbox.gif -------------------------------------------------------------------------------- /DateAsCheckbox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /DateRangePickerPCF/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended" 8 | ], 9 | "globals": { 10 | "ComponentFramework": true, 11 | "JSX":true 12 | }, 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaVersion": 12, 16 | "sourceType": "module" 17 | }, 18 | "plugins": [ 19 | "@microsoft/power-apps", 20 | "@typescript-eslint" 21 | ], 22 | "rules": { 23 | "no-unused-vars": "off" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /DateRangePickerPCF/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj 15 | 16 | # MSBuild Binary and Structured Log 17 | *.binlog 18 | -------------------------------------------------------------------------------- /DateRangePickerPCF/DateRangePickerPCF.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | DateRangePicker 12 | 333c96a7-0738-49db-94ab-18f0161e7050 13 | $(MSBuildThisFileDirectory)out\controls 14 | 15 | 16 | 17 | v4.6.2 18 | 19 | net462 20 | PackageReference 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /DateRangePickerPCF/DateRangerPickerPCF/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 1 25 | 0 26 | 27 | 28 | 1 29 | 0 30 | 31 | 32 | 33 | 34 | 35 | 46 | 47 | 48 | 49 | 50 | 54 | 55 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /DateRangePickerPCF/DateRangerPickerPCF/CustomTheme.less: -------------------------------------------------------------------------------- 1 | @primary-color:#0078D7; 2 | @border-radius: 0px; 3 | @font-family-base: Monaco, Menlo, Consolas; 4 | @font-size-base: 14px; -------------------------------------------------------------------------------- /DateRangePickerPCF/DateRangerPickerPCF/MyDateRangePicker.tsx: -------------------------------------------------------------------------------- 1 | 2 | import * as React from 'react'; 3 | import DateRangePicker from 'rsuite/DateRangePicker'; 4 | import CustomProvider from 'rsuite/CustomProvider'; 5 | import frFR from 'rsuite/locales/fr_FR'; 6 | import 'rsuite/dist/rsuite.min.css'; 7 | //import 'rsuite/styles/index.less'; 8 | import './CustomTheme.less' 9 | 10 | const { allowedMaxDays, allowedDays, allowedRange, beforeToday, afterToday, combine } = DateRangePicker; 11 | 12 | export interface IDateRangePickerProps { 13 | startDate:Date | null, 14 | endDate:Date | null, 15 | enabled:boolean, 16 | useOneCalendar:boolean, 17 | useWeeksNumber:boolean, 18 | dateFormat:string, 19 | placeholder:string, 20 | character:string, 21 | calendarCallback: (startDate:Date | null, endDate:Date | null) => void; 22 | } 23 | 24 | 25 | const MyDateRangePicker = (props:IDateRangePickerProps): JSX.Element => { 26 | 27 | type ValueType = [Date, Date]; 28 | 29 | const [startDate, setStartDate] = React.useState(props.startDate); 30 | const [endDate, setEndDate] = React.useState(props.endDate); 31 | 32 | const SetDates = (newValue: ValueType)=>{ 33 | setStartDate(newValue[0]); 34 | setEndDate(newValue[1]); 35 | } 36 | 37 | const cleanDates=(event:any)=>{ 38 | debugger; 39 | setStartDate(null); 40 | setEndDate(null); 41 | } 42 | 43 | React.useEffect(()=>{ 44 | if(startDate != props.startDate){ 45 | props.calendarCallback(startDate, endDate); 46 | } 47 | },[startDate]); 48 | 49 | React.useEffect(()=>{ 50 | if(endDate != props.endDate){ 51 | props.calendarCallback(startDate, endDate); 52 | } 53 | },[endDate]); 54 | 55 | return ( 56 | <> 57 | 58 | 76 | 77 | 78 | ) 79 | }; 80 | export default MyDateRangePicker; 81 | 82 | -------------------------------------------------------------------------------- /DateRangePickerPCF/DateRangerPickerPCF/index.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import * as ReactDOM from 'react-dom'; 3 | import MyDateRangePicker, { IDateRangePickerProps } from "./MyDateRangePicker"; 4 | import {IInputs, IOutputs} from "./generated/ManifestTypes"; 5 | 6 | export class DateRangerPicker implements ComponentFramework.StandardControl { 7 | private theContext: ComponentFramework.Context; 8 | private notifyOutputChanged: () => void; 9 | private startDate:Date | null; 10 | private endDate:Date | null; 11 | private container:HTMLDivElement; 12 | /** 13 | * Empty constructor. 14 | */ 15 | constructor() 16 | { 17 | 18 | } 19 | 20 | /** 21 | * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here. 22 | * Data-set values are not initialized here, use updateView. 23 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions. 24 | * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously. 25 | * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface. 26 | * @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content. 27 | */ 28 | public init(context: ComponentFramework.Context, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement): void 29 | { 30 | this.notifyOutputChanged = notifyOutputChanged; 31 | this.theContext = context; 32 | this.container = container; 33 | } 34 | 35 | 36 | /** 37 | * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc. 38 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions 39 | */ 40 | public updateView(context: ComponentFramework.Context): void 41 | { 42 | const props: IDateRangePickerProps = { 43 | startDate:context.parameters.StartDate.raw, 44 | endDate:context.parameters.EndDate.raw, 45 | enabled:!context.mode.isControlDisabled, 46 | placeholder: context.parameters.PlaceHolder.raw ?? "Select a date range", 47 | character : context.parameters.LinkCharacter.raw ?? " ~ ", 48 | dateFormat : context.parameters.DateFormat.raw ?? "yyyy-MM-dd", 49 | useOneCalendar: context.parameters.ShowOneCalendar.raw === "1", 50 | useWeeksNumber: context.parameters.ShowWeeksNumber.raw === "1", 51 | calendarCallback:this.calendarCallback 52 | }; 53 | var control = React.createElement( 54 | MyDateRangePicker, props 55 | ); 56 | 57 | ReactDOM.render(control, this.container); 58 | 59 | } 60 | 61 | private calendarCallback = (startDate:Date | null, endDate:Date | null)=>{ 62 | this.startDate = startDate; 63 | this.endDate = endDate; 64 | this.notifyOutputChanged(); 65 | } 66 | 67 | /** 68 | * It is called by the framework prior to a control receiving new data. 69 | * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output” 70 | */ 71 | public getOutputs(): IOutputs 72 | { 73 | return { 74 | StartDate:this.startDate ?? undefined, 75 | EndDate:this.endDate ?? undefined 76 | }; 77 | } 78 | 79 | /** 80 | * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup. 81 | * i.e. cancelling any pending remote calls, removing listeners, etc. 82 | */ 83 | public destroy(): void 84 | { 85 | // Add code to cleanup control if necessary 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /DateRangePickerPCF/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "refreshTypes": "pcf-scripts refreshTypes" 13 | }, 14 | "dependencies": { 15 | "css-loader": "^6.8.1", 16 | "material-mui-date-range-picker": "^5.0.1", 17 | "rsuite": "^5.35.1", 18 | "style-loader": "^3.3.3" 19 | }, 20 | "devDependencies": { 21 | "@microsoft/eslint-plugin-power-apps": "^0.2.6", 22 | "@types/node": "^18.8.2", 23 | "@types/powerapps-component-framework": "^1.3.4", 24 | "@types/react": "^16.8", 25 | "@types/react-dom": "^18.2.6", 26 | "@typescript-eslint/eslint-plugin": "^5.39.0", 27 | "@typescript-eslint/parser": "^5.60.1", 28 | "ajv": "^8.12.0", 29 | "eslint": "^8.24.0", 30 | "eslint-plugin-import": "^2.26.0", 31 | "eslint-plugin-node": "^11.1.0", 32 | "eslint-plugin-promise": "^6.0.1", 33 | "extract-text-webpack-plugin": "^3.0.2", 34 | "less": "^4.1.3", 35 | "less-loader": "^11.1.3", 36 | "pcf-scripts": "^1", 37 | "pcf-start": "^1", 38 | "typescript": "^4.8.4" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /DateRangePickerPCF/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /DateRangePickerPCF/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | } 6 | } -------------------------------------------------------------------------------- /DateRangePickerSolution/Build Release-DateRangePicker.bat: -------------------------------------------------------------------------------- 1 | msbuild /t:build /restore /p:configuration=Release -------------------------------------------------------------------------------- /DateRangePickerSolution/DateRangePicker.cdsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | 4f549a5e-5ffa-4301-bb56-90817172b9eb 12 | v4.6.2 13 | 14 | net462 15 | PackageReference 16 | src 17 | 18 | 19 | 24 | 25 | Unmanaged 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /DateRangePickerSolution/src/Other/Customizations.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 1033 17 | 18 | -------------------------------------------------------------------------------- /DateRangePickerSolution/src/Other/Relationships.xml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /DateRangePickerSolution/src/Other/Solution.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | DateRangePcfControl 6 | 7 | 8 | 9 | 10 | 11 | 1.0.0.0 12 | 13 | 0 14 | 15 | 16 | ZooParcBeauval 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | zoo 31 | 32 | 41110 33 | 34 | 35 |
36 | 1 37 | 1 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 1 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 | 2 88 | 1 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 1 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 |
138 |
139 | 140 | 141 |
142 |
-------------------------------------------------------------------------------- /LinearSliderWithSteps/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj -------------------------------------------------------------------------------- /LinearSliderWithSteps/LinearSliderWithSteps.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | LinearSliderWithSteps 12 | 13d64fe0-d558-45f5-89f1-004d3b336f39 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /LinearSliderWithSteps/LinearSliderWithSteps/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Whole.None 6 | Currency 7 | FP 8 | Decimal 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | Left 19 | Center 20 | Right 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /LinearSliderWithSteps/LinearSliderWithSteps/css/LinearSliderWithSteps.css: -------------------------------------------------------------------------------- 1 | input[type=range].linearslider { 2 | margin: 1px 0; 3 | background:transparent; 4 | -webkit-appearance:none; 5 | width:100%;padding:0; 6 | height:24px; 7 | -webkit-tap-highlight-color:transparent 8 | } 9 | input[type=range].linearslider:focus { 10 | outline: none; 11 | } 12 | input[type=range].linearslider::-webkit-slider-runnable-track { 13 | background: #666; 14 | height:2px; 15 | cursor:pointer 16 | } 17 | input[type=range].linearslider::-webkit-slider-thumb { 18 | background: #666; 19 | border:0 solid #f00; 20 | height:24px; 21 | width:10px; 22 | border-radius:48px; 23 | cursor:pointer; 24 | opacity:1; 25 | -webkit-appearance:none; 26 | margin-top:-12px 27 | } 28 | input[type=range].linearslider::-moz-range-track { 29 | background: #666; 30 | height:2px; 31 | cursor:pointer 32 | } 33 | input[type=range].linearslider::-moz-range-thumb { 34 | background: #666; 35 | border:0 solid #f00; 36 | height:24px; 37 | width:10px; 38 | border-radius:48px; 39 | cursor:pointer; 40 | opacity:1; 41 | -webkit-appearance:none; 42 | margin-top:-12px 43 | } 44 | input[type=range].linearslider::-ms-track { 45 | background: #666; 46 | height:2px; 47 | cursor:pointer 48 | } 49 | input[type=range].linearslider::-ms-thumb { 50 | background: #666; 51 | border:0 solid #f00; 52 | height:24px; 53 | width:10px; 54 | border-radius:48px; 55 | cursor:pointer; 56 | opacity:1; 57 | -webkit-appearance:none; 58 | 59 | } -------------------------------------------------------------------------------- /LinearSliderWithSteps/LinearSliderWithSteps/imgs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/LinearSliderWithSteps/LinearSliderWithSteps/imgs/screenshot.png -------------------------------------------------------------------------------- /LinearSliderWithSteps/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import pluginReact from "eslint-plugin-react"; 5 | import { defineConfig } from "eslint/config"; 6 | 7 | 8 | export default defineConfig([ 9 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] }, 10 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], languageOptions: { globals: globals.browser } }, 11 | tseslint.configs.recommended, 12 | pluginReact.configs.flat.recommended, 13 | ]); -------------------------------------------------------------------------------- /LinearSliderWithSteps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.25.1", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint": "^9.25.1", 29 | "eslint-plugin-promise": "^7.1.0", 30 | "eslint-plugin-react": "^7.37.5", 31 | "globals": "^15.15.0", 32 | "pcf-scripts": "^1", 33 | "pcf-start": "^1", 34 | "react": "^16.14.0", 35 | "typescript": "^4.9.5", 36 | "typescript-eslint": "^8.31.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LinearSliderWithSteps/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /LinearSliderWithSteps/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /LookupToPicklist/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj 15 | 16 | # MSBuild Binary and Structured Log 17 | *.binlog 18 | 19 | # Visual Studio cache/options directory 20 | /.vs 21 | 22 | # macos 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /LookupToPicklist/LooklupToPicklist/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 1 12 | 0 13 | 14 | 15 | 16 | 1 17 | 0 18 | 19 | 20 | 1 21 | 0 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /LookupToPicklist/LooklupToPicklist/Interfaces.ts: -------------------------------------------------------------------------------- 1 | import { ComboboxProps, Theme } from '@fluentui/react-components'; 2 | import { IInputs } from './generated/ManifestTypes'; 3 | 4 | export interface IRecordCategory{ 5 | title:string, 6 | key:string 7 | records: IRecord[], 8 | type:string 9 | } 10 | 11 | export interface IRecord { 12 | key:string, 13 | text:string, 14 | isAction?: boolean, 15 | type?:string 16 | } 17 | 18 | export interface ILookupToComboBoxProps extends ComboboxProps { 19 | viewId: string, 20 | entityName: string, 21 | isDisabled:boolean, 22 | context: ComponentFramework.Context, 23 | selectedId: string, 24 | parentRecordId : string | undefined, 25 | notifyOutputChanged: (value : ComponentFramework.LookupValue | undefined) => void, 26 | } 27 | 28 | export interface IMru{ 29 | objectId:string, 30 | title:string 31 | } 32 | -------------------------------------------------------------------------------- /LookupToPicklist/LooklupToPicklist/img/LookupToPicklist_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/LookupToPicklist/LooklupToPicklist/img/LookupToPicklist_preview.png -------------------------------------------------------------------------------- /LookupToPicklist/LooklupToPicklist/index.ts: -------------------------------------------------------------------------------- 1 | import { IInputs, IOutputs } from "./generated/ManifestTypes"; 2 | import { LookupCombobox } from "./LookupCombobox"; 3 | import * as React from "react"; 4 | 5 | export class LookupToPicklist implements ComponentFramework.ReactControl { 6 | private notifyOutputChanged: () => void; 7 | private entityName: string; 8 | private entityIdFieldName: string; 9 | private entityNameFieldName: string; 10 | private entityDisplayName: string; 11 | private viewId: string; 12 | private currentValue?: ComponentFramework.LookupValue[]; 13 | private newlyCreatedId: string|null; 14 | private parentId: string|undefined; 15 | /** 16 | * Empty constructor. 17 | */ 18 | constructor() { 19 | // Empty 20 | } 21 | 22 | /** 23 | * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here. 24 | * Data-set values are not initialized here, use updateView. 25 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions. 26 | * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously. 27 | * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface. 28 | */ 29 | public init( 30 | context: ComponentFramework.Context, 31 | notifyOutputChanged: () => void, 32 | state: ComponentFramework.Dictionary 33 | ): void { 34 | this.notifyOutputChanged = notifyOutputChanged; 35 | this.entityName = context.parameters.lookup.getTargetEntityType() 36 | this.viewId = context.parameters.lookup.getViewId(); 37 | } 38 | 39 | private renderControl(context: ComponentFramework.Context) : React.ReactElement { 40 | 41 | let recordId = context.parameters.lookup.raw != null && context.parameters.lookup.raw.length > 0 42 | ? context.parameters.lookup.raw[0].id?.replace(/[{}]/g,"").toLowerCase() 43 | : '---' 44 | 45 | if(this.newlyCreatedId){ 46 | recordId = this.newlyCreatedId; 47 | this.newlyCreatedId = null; 48 | } 49 | 50 | const parentId = context.parameters.dependantLookup.raw?.length > 0 ? context.parameters.dependantLookup.raw[0].id : "---" 51 | 52 | return React.createElement(LookupCombobox, { 53 | context: context, 54 | selectedId: recordId, 55 | selectedOptions: [recordId], 56 | viewId: this.viewId, 57 | entityName: this.entityName, 58 | isDisabled: context.mode.isControlDisabled, 59 | notifyOutputChanged: this.notifyChange.bind(this), 60 | parentRecordId: parentId, 61 | }) 62 | } 63 | 64 | public notifyChange(value : ComponentFramework.LookupValue | undefined) : void { 65 | this.currentValue = value? [value] : undefined; 66 | this.notifyOutputChanged(); 67 | } 68 | 69 | /** 70 | * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc. 71 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions 72 | * @returns ReactElement root react element for the control 73 | */ 74 | public updateView(context: ComponentFramework.Context): React.ReactElement { 75 | 76 | if(context.updatedProperties.includes("dependantLookup")){ 77 | const newParentId = context.parameters.dependantLookup.raw.length > 0 ? context.parameters.dependantLookup.raw[0].id : undefined; 78 | if(newParentId?.replace(/[{}]/g,"") !== this.parentId?.replace(/[{}]/g,"")){ 79 | this.parentId = newParentId; 80 | this.currentValue = []; 81 | this.notifyOutputChanged(); 82 | } 83 | } 84 | else if(context.updatedProperties.includes("lookup")){ 85 | return this.renderControl(context); 86 | } 87 | return this.renderControl(context); 88 | } 89 | 90 | /** 91 | * It is called by the framework prior to a control receiving new data. 92 | * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as "bound" or "output" 93 | */ 94 | public getOutputs(): IOutputs { 95 | return { 96 | lookup: this.currentValue, 97 | }; 98 | } 99 | 100 | /** 101 | * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup. 102 | * i.e. cancelling any pending remote calls, removing listeners, etc. 103 | */ 104 | public destroy(): void { 105 | // Add code to cleanup control if necessary 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /LookupToPicklist/LookupToPicklist.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | LookupToPicklist 12 | cfb0909b-9c4a-4a4e-af4e-97a8c88b0dfd 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /LookupToPicklist/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslintjs from "@eslint/js"; 2 | import microsoftPowerApps from "@microsoft/eslint-plugin-power-apps"; 3 | import pluginPromise from "eslint-plugin-promise"; 4 | import reactPlugin from "eslint-plugin-react"; 5 | import globals from "globals"; 6 | import typescriptEslint from "typescript-eslint"; 7 | 8 | /** @type {import('eslint').Linter.Config[]} */ 9 | export default [ 10 | { 11 | ignores: ["**/generated"], 12 | }, 13 | eslintjs.configs.recommended, 14 | ...typescriptEslint.configs.recommendedTypeChecked, 15 | ...typescriptEslint.configs.stylisticTypeChecked, 16 | pluginPromise.configs["flat/recommended"], 17 | microsoftPowerApps.configs.paCheckerHosted, 18 | reactPlugin.configs.flat.recommended, 19 | { 20 | plugins: { 21 | "@microsoft/power-apps": microsoftPowerApps, 22 | }, 23 | 24 | languageOptions: { 25 | globals: { 26 | ...globals.browser, 27 | ComponentFramework: true, 28 | }, 29 | parserOptions: { 30 | ecmaVersion: 2020, 31 | sourceType: "module", 32 | projectService: true, 33 | tsconfigRootDir: import.meta.dirname, 34 | }, 35 | }, 36 | 37 | rules: { 38 | "@typescript-eslint/no-unused-vars": "off", 39 | "@typescript-eslint/no-explicit-any": "off", 40 | "@typescript-eslint/no-unsafe-member-access": "off", 41 | "@typescript-eslint/no-unsafe-call": "off", 42 | "@typescript-eslint/no-misused-promises": "off", 43 | }, 44 | settings: { 45 | react: { 46 | version: "detect", 47 | }, 48 | }, 49 | }, 50 | ]; 51 | -------------------------------------------------------------------------------- /LookupToPicklist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "react": "16.14.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "react-dom": "16.14.0" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "^9.17.0", 22 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 23 | "@types/powerapps-component-framework": "^1.3.15", 24 | "@types/react": "^16.14.60", 25 | "@types/react-dom": "^16.9.24", 26 | "eslint-plugin-promise": "^7.1.0", 27 | "eslint-plugin-react": "^7.37.2", 28 | "globals": "^15.13.0", 29 | "pcf-scripts": "^1", 30 | "pcf-start": "^1", 31 | "react": "^16.14.0", 32 | "typescript": "^4.9.5", 33 | "typescript-eslint": "^8.18.1" 34 | } 35 | } -------------------------------------------------------------------------------- /LookupToPicklist/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /LookupToPicklist/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /MscrmToolsPCFControls/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # msbuild output directories 4 | /bin 5 | /obj -------------------------------------------------------------------------------- /MscrmToolsPCFControls/Build Release-DateRangePicker.bat: -------------------------------------------------------------------------------- 1 | msbuild /t:build /restore /p:configuration=Release -------------------------------------------------------------------------------- /MscrmToolsPCFControls/Build Release.bat: -------------------------------------------------------------------------------- 1 | msbuild /t:build /restore /p:configuration=Release -------------------------------------------------------------------------------- /MscrmToolsPCFControls/MscrmToolsPCFControls.cdsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | 4f549a5e-5ffa-4301-bb56-90817172b9eb 12 | v4.6.2 13 | 14 | net462 15 | PackageReference 16 | src 17 | 18 | 19 | 24 | 25 | Both 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /MscrmToolsPCFControls/src/Other/Customizations.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 1033 17 | 18 | -------------------------------------------------------------------------------- /MscrmToolsPCFControls/src/Other/Relationships.xml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /MscrmToolsPCFControls/src/Other/Solution.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | MscrmToolsPCFControls 6 | 7 | 8 | 9 | 10 | 11 | 1.12.7.0 12 | 13 | 2 14 | 15 | 16 | MscrmTools 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | mctools 31 | 32 | 54953 33 | 34 | 35 |
36 | 1 37 | 1 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 1 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 | 2 88 | 1 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 1 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 |
138 |
139 | 140 | 141 |
142 |
-------------------------------------------------------------------------------- /NNCheckboxes/.gitignore: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | NNCheckboxes 7 | 97aafff1-a4ee-42c9-bd28-998ab205ed13 8 | $(MSBuildThisFileDirectory)out\controls 9 | production 10 | 11 | 12 | 13 | PackageReference 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Always 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | True 17 | False 18 | 19 | 20 | 21 | 22 | 1 23 | 0 24 | 25 | 26 | 1 27 | 0 28 | 29 | 30 | 1 31 | 0 32 | 33 | 34 | SingleLine.Text 35 | OptionSet 36 | TwoOptions 37 | 38 | 39 | Lookup.Simple 40 | SingleLine.Text 41 | OptionSet 42 | TwoOptions 43 | 44 | 45 | SingleLine.Text 46 | OptionSet 47 | 48 | 49 | SingleLine.Text 50 | Multiple 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/Solution/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /obj -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/Solution/Other/Customizations.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 1033 17 | 18 | -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/Solution/Other/Relationships.xml: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/Solution/Other/Solution.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Solution 6 | 7 | 8 | 9 | 10 | 11 | 1.0.8 12 | 13 | 2 14 | 15 | 16 | MscrmTools 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | mctools 31 | 32 | 54953 33 | 34 | 35 |
36 | 1 37 | 1 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 1 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
86 |
87 | 2 88 | 1 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 1 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 |
137 |
138 |
139 | 140 | 141 |
142 |
-------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/Solution/Solution.cdsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | 4315b98f-4b2a-46f9-86fd-82f871bae6f6 12 | v4.6.2 13 | 14 | net462 15 | PackageReference 16 | 17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/css/NNCheckboxes.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | input[type=checkbox] + label { 6 | vertical-align: middle; 7 | position: relative; 8 | bottom: 1px; 9 | font-weight: bold; 10 | } 11 | 12 | input[type=checkbox]:checked + label{ 13 | font-weight: normal; 14 | text-decoration: line-through; 15 | } 16 | 17 | 18 | div.nncb-main{ 19 | margin-top:10px; 20 | } 21 | 22 | 23 | /* Customize the label (the container) */ 24 | .nncb-container { 25 | display: block; 26 | position: relative; 27 | padding-left: 25px !important; 28 | padding-bottom: 1px; 29 | margin-bottom: 12px; 30 | margin-right:10px; 31 | border-radius: 5px; 32 | cursor: pointer; 33 | -webkit-user-select: none; 34 | -moz-user-select: none; 35 | -ms-user-select: none; 36 | user-select: none; 37 | font-family: "Segoe UI",tahoma,Arial; 38 | font-size: 14px; 39 | color: #444444; 40 | white-space:normal; 41 | } 42 | 43 | /* Hide the browser's default checkbox */ 44 | .nncb-container input { 45 | position: absolute; 46 | opacity: 0; 47 | cursor: pointer; 48 | } 49 | 50 | /* Create a custom checkbox */ 51 | .nncb-checkmark { 52 | position: absolute; 53 | top: 3px; 54 | left: 3px; 55 | height: 12px; 56 | width: 12px; 57 | background-color: #fff; 58 | border:solid 1px #444444; 59 | } 60 | 61 | /* On mouse-over, add a grey background color */ 62 | .nncb-container:hover input ~ .nncb-checkmark { 63 | background-color: #ccc; 64 | } 65 | 66 | /* When the checkbox is checked, add a blue background */ 67 | .nncb-container input:checked ~ .nncb-checkmark { 68 | background-color: #fff; 69 | } 70 | 71 | /* Create the checkmark/indicator (hidden when not checked) */ 72 | .nncb-checkmark:after { 73 | content: ""; 74 | position: absolute; 75 | display: none; 76 | } 77 | 78 | /* Show the checkmark when checked */ 79 | .nncb-container input:checked ~ .nncb-checkmark:after { 80 | display: block; 81 | } 82 | 83 | /* Style the checkmark/indicator */ 84 | .nncb-container .nncb-checkmark:after { 85 | left: 3px !important; 86 | top: 0px !important; 87 | width: 4px; 88 | height: 8px; 89 | border: solid #444444; 90 | border-width: 0 2px 2px 0; 91 | -webkit-transform: rotate(45deg); 92 | -ms-transform: rotate(45deg); 93 | transform: rotate(45deg); 94 | } 95 | 96 | div.nncb-flex{ 97 | display: flex; 98 | flex-wrap : wrap; 99 | flex-grow:1; 100 | } 101 | 102 | a.nncb-category-link:hover, 103 | a.nncb-category-link:active, 104 | a.nncb-category-link:visited 105 | { 106 | float:right; 107 | cursor: pointer; 108 | color:rgb(17, 96, 183); 109 | } 110 | 111 | div.nncb-flex >div { 112 | flex: 0 50%; 113 | margin-bottom:5px; 114 | font-family: "Segoe UI",tahoma,Arial; 115 | font-size: 14px; 116 | color: #444444; 117 | } 118 | 119 | /* toggle switch */ 120 | /* The switch - the box around the slider */ 121 | .nncb-container-switch { 122 | position: relative; 123 | display: inline-block; 124 | width: 40px; 125 | height: 22px; 126 | } 127 | 128 | /* Hide default HTML checkbox */ 129 | .nncb-container-switch input { 130 | opacity: 0; 131 | width: 0; 132 | height: 0; 133 | } 134 | 135 | /* The slider */ 136 | .nncb-slider { 137 | position: absolute; 138 | cursor: pointer; 139 | top: 0; 140 | left: 0; 141 | right: 0; 142 | bottom: 0; 143 | background-color: /*#ccc*/#CC0000; 144 | -webkit-transition: .4s; 145 | transition: .4s; 146 | } 147 | 148 | .nncb-slider:before { 149 | position: absolute; 150 | content: ""; 151 | height: 14px; 152 | width: 14px; 153 | left: 4px; 154 | bottom: 4px; 155 | background-color: white; 156 | -webkit-transition: .4s; 157 | transition: .4s; 158 | } 159 | 160 | input:checked + .nncb-slider { 161 | background-color: /*#2196F3*/#008800; 162 | } 163 | 164 | /* input:focus + .nncb-slider { 165 | box-shadow: 0 0 1px #2196F3; 166 | } */ 167 | 168 | input:checked + .nncb-slider:before { 169 | -webkit-transform: translateX(18px); 170 | -ms-transform: translateX(18px); 171 | transform: translateX(18px); 172 | } 173 | 174 | /* Rounded sliders */ 175 | .nncb-slider.nncb-round { 176 | border-radius: 34px; 177 | } 178 | 179 | .nncb-slider.nncb-round:before { 180 | border-radius: 50%; 181 | } 182 | 183 | span.nncb-switch-label{ 184 | padding-left:5px; 185 | white-space: normal; 186 | } -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/NNCheckboxes/imgs/logo.png -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/imgs/nncheckboxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/NNCheckboxes/imgs/nncheckboxes.png -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/referential.ts: -------------------------------------------------------------------------------- 1 | const conditionOperators = ["eq", 2 | "ne", 3 | "gt", 4 | "lt", 5 | "ge", 6 | "le", 7 | "like", 8 | "not-like", 9 | "in", 10 | "not-in", 11 | "between", 12 | "not-between", 13 | "null", 14 | "not-null", 15 | "yesterday", 16 | "today", 17 | "tomorrow", 18 | "last-seven-days", 19 | "next-seven-days", 20 | "last-week", 21 | "this-week", 22 | "next-week", 23 | "last-month", 24 | "this-month", 25 | "next-month", 26 | "on", 27 | "on-or-before", 28 | "on-or-after", 29 | "last-year", 30 | "this-year", 31 | "next-year", 32 | "last-x-hours", 33 | "next-x-hours", 34 | "last-x-days", 35 | "next-x-days", 36 | "last-x-weeks", 37 | "next-x-weeks", 38 | "last-x-months", 39 | "next-x-months", 40 | "last-x-years", 41 | "next-x-years", 42 | "eq-userid", 43 | "ne-userid", 44 | "eq-businessid", 45 | "ne-businessid", 46 | "child-of", 47 | "mask", 48 | "not-mask", 49 | "masks-select", 50 | "contains", 51 | "does-not-contain", 52 | "eq-language", 53 | "not-on", 54 | "olderthan-x-months", 55 | "begins-with", 56 | "not-beginwith", 57 | "ends-with", 58 | "not-endwith", 59 | "this-fiscal-year", 60 | "this-fiscal-period", 61 | "next-fiscal-year", 62 | "next-fiscal-period", 63 | "last-fiscal-year", 64 | "last-fiscal-period", 65 | "last-x-fiscal-years", 66 | "last-x-fiscal-periods", 67 | "next-x-fiscal-years", 68 | "next-x-fiscal-periods", 69 | "infiscalyear", 70 | "in-fiscal-period", 71 | "in-fiscal-period-and-year", 72 | "in-or-before-fiscal-period-and-year", 73 | "in-or-after-fiscal-period-and-year", 74 | "eq-userteams", 75 | "eq-useroruserteams", 76 | "under", 77 | "not-under", 78 | "under-or-equal", 79 | "above", 80 | "above-or-equal", 81 | "eq-useroruserhierarchy", 82 | "eq-useroruserhierarchyandteams", 83 | "olderthan-x-years", 84 | "olderthan-x-weeks", 85 | "olderthan-x-days", 86 | "olderthan-x-hours", 87 | "olderthan-x-minutes", 88 | "contain-values", 89 | "not-contain-values", 90 | "eq-rolebusinessid" 91 | ]; -------------------------------------------------------------------------------- /NNCheckboxes/NNCheckboxes/reldef.ts: -------------------------------------------------------------------------------- 1 | export class RelationshipInfo{ 2 | public Entity1LogicalName:string; 3 | public Entity1AttributeName:string; 4 | public Entity2LogicalName:string; 5 | public Entity2AttributeName:string; 6 | public Name:string; 7 | } -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/ColorAndGroups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/ColorAndGroups.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Configuration.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Control.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample1.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample10.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample2.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample3.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample4.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample5.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample6.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample7.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample8.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/Sample9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/Sample9.png -------------------------------------------------------------------------------- /NNCheckboxes/Screenshots/video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/NNCheckboxes/Screenshots/video.gif -------------------------------------------------------------------------------- /NNCheckboxes/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import js from "@eslint/js"; 2 | import globals from "globals"; 3 | import tseslint from "typescript-eslint"; 4 | import pluginReact from "eslint-plugin-react"; 5 | import { defineConfig } from "eslint/config"; 6 | import microsoftPowerApps from "@microsoft/eslint-plugin-power-apps"; 7 | 8 | 9 | export default defineConfig([ 10 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], plugins: { js }, extends: ["js/recommended"] }, 11 | { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], languageOptions: { globals: globals.browser } }, 12 | { 13 | ignores: ["**/generated"], 14 | }, 15 | tseslint.configs.recommended, 16 | pluginReact.configs.flat.recommended, 17 | { 18 | plugins: { 19 | "@microsoft/power-apps": microsoftPowerApps, 20 | }, 21 | rules: { 22 | "@typescript-eslint/no-unused-vars": "off", 23 | "@typescript-eslint/no-explicit-any": "off", 24 | "@typescript-eslint/no-unsafe-member-access": "off", 25 | "@typescript-eslint/no-unsafe-call": "off", 26 | "@typescript-eslint/no-misused-promises": "off", 27 | "@typescript-eslint/no-empty-object-types": "off", 28 | }, 29 | settings: { 30 | react: { 31 | version: "detect", 32 | }, 33 | }, 34 | } 35 | ]); -------------------------------------------------------------------------------- /NNCheckboxes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.25.1", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint": "^9.25.1", 29 | "eslint-plugin-promise": "^7.1.0", 30 | "eslint-plugin-react": "^7.37.5", 31 | "globals": "^15.15.0", 32 | "pcf-scripts": "^1", 33 | "pcf-start": "^1", 34 | "react": "^16.14.0", 35 | "typescript": "^4.9.5", 36 | "typescript-eslint": "^8.31.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NNCheckboxes/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /NNCheckboxes/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /ReactNotifier/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj 15 | 16 | # MSBuild Binary and Structured Log 17 | *.binlog 18 | 19 | # Visual Studio cache/options directory 20 | /.vs 21 | 22 | # macos 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /ReactNotifier/ReactNotifier.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | ReactNotfier 12 | e033d7dd-ada1-4812-b692-c9d6c4bf9ef5 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ReactNotifier/ReactNotifier/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Info 9 | Warning 10 | Error 11 | Blocked 12 | SeverWarning 13 | Success 14 | 15 | 16 | 17 | 18 | Yes 19 | No 20 | 21 | 22 | Yes 23 | No 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ReactNotifier/ReactNotifier/NotificationControl.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { 4 | MessageBar, 5 | Link, 6 | FluentProvider, 7 | IdPrefixProvider, 8 | makeStyles, 9 | MessageBarBody, 10 | MessageBarTitle, 11 | Theme, 12 | MessageBarIntent, 13 | } from "@fluentui/react-components"; 14 | 15 | export interface IMessageProps { 16 | messageType?: MessageBarIntent | undefined; 17 | messageText?: string | null; 18 | showLink?: boolean; 19 | link?: string | null; 20 | linkText?: string | null; 21 | theme: Theme; 22 | title: string | null; 23 | isMultiline?: boolean; 24 | } 25 | 26 | const _useStyles = makeStyles({ 27 | root: { 28 | width: "100%", 29 | }, 30 | }); 31 | 32 | export const NotificationControl: React.FC = (props) => { 33 | const styles = _useStyles(); 34 | return ( 35 | 36 | 37 | 38 | 39 | {(props.title ? {props.title} :<>)} 40 | {props.messageText} 41 | {" "} 42 | {(props.link? {props.linkText} : <>)} 43 | 44 | 45 | 46 | 47 | ); 48 | }; 49 | -------------------------------------------------------------------------------- /ReactNotifier/ReactNotifier/imgs/ReactNotification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/ReactNotifier/ReactNotifier/imgs/ReactNotification.png -------------------------------------------------------------------------------- /ReactNotifier/ReactNotifier/index.ts: -------------------------------------------------------------------------------- 1 | import { IInputs, IOutputs } from "./generated/ManifestTypes"; 2 | import * as React from "react"; 3 | import { IMessageProps, NotificationControl } from "./NotificationControl"; 4 | import { MessageBarIntent, Theme, webLightTheme } from "@fluentui/react-components"; 5 | export class SimpleNotification 6 | implements ComponentFramework.ReactControl 7 | { 8 | /** 9 | * Empty constructor. 10 | */ 11 | constructor() { 12 | // Empty 13 | } 14 | 15 | /** 16 | * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here. 17 | * Data-set values are not initialized here, use updateView. 18 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions. 19 | * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously. 20 | * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface. 21 | */ 22 | public init( 23 | context: ComponentFramework.Context, 24 | notifyOutputChanged: () => void, 25 | state: ComponentFramework.Dictionary 26 | ): void { 27 | // Add code to initialize control if necessary 28 | context.mode.trackContainerResize(true); 29 | 30 | } 31 | 32 | /** 33 | * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc. 34 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions 35 | * @returns ReactElement root react element for the control 36 | */ 37 | public updateView( 38 | context: ComponentFramework.Context 39 | ): React.ReactElement { 40 | const props: IMessageProps = { 41 | messageType: "info", 42 | messageText: context.parameters.message.raw ?? "", 43 | showLink: context.parameters.showLink.raw === "Yes", 44 | link: context.parameters.link.raw, 45 | linkText: context.parameters.linkText.raw, 46 | theme: (context.fluentDesignLanguage?.tokenTheme ?? webLightTheme) as Theme, 47 | title: context.parameters.title.raw ?? "", 48 | isMultiline : context.parameters.isMultiLine.raw === "Yes", 49 | }; 50 | 51 | switch (context.parameters.messageType.raw) { 52 | case "Blocked": 53 | case "Error": 54 | props.messageType = "error"; 55 | break; 56 | 57 | default: 58 | case "Info": 59 | props.messageType = "info"; 60 | break; 61 | case "Warning": 62 | case "SeverWarning": 63 | props.messageType = "warning"; 64 | break; 65 | case "Success": 66 | props.messageType = "success"; 67 | break; 68 | } 69 | 70 | return React.createElement(NotificationControl, props); 71 | } 72 | 73 | /** 74 | * It is called by the framework prior to a control receiving new data. 75 | * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as "bound" or "output" 76 | */ 77 | public getOutputs(): IOutputs { 78 | return {}; 79 | } 80 | 81 | /** 82 | * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup. 83 | * i.e. cancelling any pending remote calls, removing listeners, etc. 84 | */ 85 | public destroy(): void { 86 | // Add code to cleanup control if necessary 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ReactNotifier/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslintjs from "@eslint/js"; 2 | import microsoftPowerApps from "@microsoft/eslint-plugin-power-apps"; 3 | import pluginPromise from "eslint-plugin-promise"; 4 | import reactPlugin from "eslint-plugin-react"; 5 | import globals from "globals"; 6 | import typescriptEslint from "typescript-eslint"; 7 | 8 | /** @type {import('eslint').Linter.Config[]} */ 9 | export default [ 10 | { 11 | ignores: ["**/generated"], 12 | }, 13 | eslintjs.configs.recommended, 14 | ...typescriptEslint.configs.recommendedTypeChecked, 15 | ...typescriptEslint.configs.stylisticTypeChecked, 16 | pluginPromise.configs["flat/recommended"], 17 | microsoftPowerApps.configs.paCheckerHosted, 18 | reactPlugin.configs.flat.recommended, 19 | { 20 | plugins: { 21 | "@microsoft/power-apps": microsoftPowerApps, 22 | }, 23 | 24 | languageOptions: { 25 | globals: { 26 | ...globals.browser, 27 | ComponentFramework: true, 28 | }, 29 | parserOptions: { 30 | ecmaVersion: 2020, 31 | sourceType: "module", 32 | projectService: true, 33 | tsconfigRootDir: import.meta.dirname, 34 | }, 35 | }, 36 | 37 | rules: { 38 | "@typescript-eslint/no-unused-vars": "off", 39 | }, 40 | settings: { 41 | react: { 42 | version: "detect", 43 | }, 44 | }, 45 | }, 46 | ]; 47 | -------------------------------------------------------------------------------- /ReactNotifier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "react": "16.14.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "react-dom": "16.14.0" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "^9.17.0", 22 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 23 | "@types/powerapps-component-framework": "^1.3.15", 24 | "@types/react": "^16.14.60", 25 | "@types/react-dom": "^16.9.24", 26 | "eslint-plugin-promise": "^7.1.0", 27 | "eslint-plugin-react": "^7.37.2", 28 | "globals": "^15.13.0", 29 | "pcf-scripts": "^1", 30 | "pcf-start": "^1", 31 | "react": "^16.14.0", 32 | "typescript": "^4.9.5", 33 | "typescript-eslint": "^8.18.1" 34 | } 35 | } -------------------------------------------------------------------------------- /ReactNotifier/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /ReactNotifier/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /YearDropdown/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:react/recommended" 9 | ], 10 | "parser": "@typescript-eslint/parser", 11 | "parserOptions": { 12 | "ecmaVersion": 12, 13 | "sourceType": "module" 14 | }, 15 | "plugins": [ 16 | "@typescript-eslint" 17 | ], 18 | "rules": { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /YearDropdown/.gitignore: -------------------------------------------------------------------------------- 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 | # msbuild output directories 13 | /bin 14 | /obj 15 | 16 | # MSBuild Binary and Structured Log 17 | *.binlog 18 | 19 | # Visual Studio cache/options directory 20 | /.vs 21 | 22 | # macos 23 | .DS_Store 24 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown.pcfproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\PowerApps 5 | 6 | 7 | 8 | 9 | 10 | 11 | YearDropdown 12 | 2ad819a5-c9dd-4cf7-bc46-c6900ac7327c 13 | $(MSBuildThisFileDirectory)out\controls 14 | production 15 | 16 | 17 | 18 | v4.6.2 19 | 20 | net462 21 | PackageReference 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:react/recommended" 9 | ], 10 | "globals": { 11 | "ComponentFramework": true 12 | }, 13 | "parser": "@typescript-eslint/parser", 14 | "parserOptions": { 15 | "ecmaVersion": 12, 16 | "sourceType": "module" 17 | }, 18 | "plugins": [ 19 | "@microsoft/power-apps", 20 | "@typescript-eslint" 21 | ], 22 | "rules": { 23 | "no-unused-vars": "off" 24 | }, 25 | "settings": { 26 | "react": { 27 | "version": "detect" 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/ControlManifest.Input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Whole.None 13 | DateAndTime.DateOnly 14 | DateAndTime.DateAndTime 15 | SingleLine.Text 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/components/DropdownNew.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { IRecordSelectorProps } from "./IRecordSelectorProps"; 3 | import { Dropdown, FluentProvider, IdPrefixProvider, Input, makeStyles, Option } from "@fluentui/react-components"; 4 | 5 | const _useStyles = makeStyles({ 6 | root: { 7 | width: "100%", 8 | } 9 | }); 10 | 11 | export const DropdownNew: React.FC = (props) => { 12 | const selectString = "--Select--"; 13 | const [placeholder, setPlaceholder] = React.useState("---"); 14 | const [dropdownIconVisible, setDropdownIconVisible] = React.useState(false); 15 | 16 | const styles = _useStyles(); 17 | const myTheme = props.isDisabled ? { 18 | ...props.theme, 19 | colorCompoundBrandStroke: props.theme?.colorNeutralStroke1, 20 | colorCompoundBrandStrokeHover: props.theme?.colorNeutralStroke1Hover, 21 | colorCompoundBrandStrokePressed: props.theme?.colorNeutralStroke1Pressed, 22 | colorCompoundBrandStrokeSelected: props.theme?.colorNeutralStroke1Selected, 23 | backgroundColor: props.theme?.colorNeutralBackground3, 24 | } 25 | : 26 | props.theme; 27 | 28 | return ( 29 |
30 | 31 | 32 | {props.isDisabled? 33 | 39 | : 40 | { 47 | setPlaceholder(selectString); 48 | setDropdownIconVisible(true); 49 | }} 50 | onMouseLeave={() => { 51 | setPlaceholder("---"); 52 | setDropdownIconVisible(false); 53 | }} 54 | onBlur={() => { 55 | setPlaceholder("---"); 56 | setDropdownIconVisible(false); 57 | }} 58 | onOptionSelect={(e, option) => { 59 | if (!option?.optionValue) { 60 | props.onChange(undefined); 61 | return; 62 | } 63 | 64 | props.onChange(props.availableOptions.find(o => o.text === option.optionValue)!); 65 | }} 66 | > 67 | {props.availableOptions.map(option => ( 68 | 75 | ))} 76 | 77 | } 78 | 79 | 80 |
81 | ); 82 | } -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/components/DropdownOld.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Dropdown, IDropdownOption, IDropdownStyleProps, IDropdownStyles } from '@fluentui/react/lib/Dropdown'; 3 | import { IRecordSelectorProps } from "./IRecordSelectorProps"; 4 | 5 | export const DropdownOld: React.FunctionComponent = props => { 6 | return ( 7 | { 12 | props.onChange(option); 13 | }} 14 | styles={dropdownStyles} 15 | />); 16 | } 17 | 18 | const colorFocus = "#a9a9a9"; 19 | 20 | export const dropdownStyles = (props: IDropdownStyleProps):Partial => ({ 21 | title: [{ 22 | color: "black", 23 | display: "block", 24 | fontWeight: props.isOpen===true ? "400" : "600", 25 | fontStretch: "normal", 26 | borderWidth: "1px", 27 | borderStyle: "solid", 28 | borderColor: props.isOpen===true ? "black" : "transparent", 29 | backgroundColor : "transparent", 30 | outline: "none", 31 | outlineColor: "transparent", 32 | outlineOffset: "0", 33 | boxSizing: "border-box", 34 | height: "33px", 35 | width: "100%", 36 | selectors: { 37 | ':hover': { 38 | borderColor: "black", 39 | borderWidth:"1px", 40 | fontWeight : props.disabled === true ? "600" : "400", 41 | backgroundColor : props.disabled === true ? "#E2E2E2" : "transparent", 42 | boxShadow: "none" 43 | } 44 | } 45 | }], 46 | dropdown: [{ 47 | outline: "none", 48 | textAlign:"left", 49 | border: "1px solid transparent", 50 | outlineColor: "transparent", 51 | outlineOffset: "0", 52 | boxShadow: "none", 53 | selectors:{ 54 | ":focus:after": { 55 | outline: "none", 56 | // border: "1px solid black", 57 | border: props.disabled===true ? "1px solid transparent" : `1px solid ${colorFocus}`, 58 | outlineColor: "transparent", 59 | boxShadow: "none" 60 | } 61 | } 62 | }], 63 | dropdownItem: [{ 64 | display: "inline-flex", 65 | selectors: { 66 | ":hover": { 67 | color: "black" 68 | } 69 | } 70 | }], 71 | dropdownItemSelected: [{ 72 | display: "inline-flex", 73 | selectors: { 74 | ":hover": { 75 | color: "black" 76 | } 77 | } 78 | }], 79 | caretDown :[{ 80 | color: props.isOpen===true? colorFocus : "transparent" 81 | }], 82 | caretDownWrapper: [{ 83 | borderLeft: props.isOpen===true ? `1px solid ${colorFocus}` : "none", 84 | paddingLeft: "7px" 85 | }] 86 | }); 87 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/components/IRecordSelectorProps.ts: -------------------------------------------------------------------------------- 1 | import { IDropdownOption } from '@fluentui/react/lib/Dropdown'; 2 | import { Theme } from "@fluentui/react-components"; 3 | 4 | export interface IRecordSelectorProps { 5 | selectedValue: string | number; 6 | availableOptions: IDropdownOption[]; 7 | isDisabled: boolean; 8 | onChange: (selectedOption?: IDropdownOption) => void; 9 | theme?: Theme 10 | } -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/components/RecordSelector.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Dropdown, IDropdownOption, IDropdownStyleProps, IDropdownStyles } from '@fluentui/react/lib/Dropdown'; 3 | import { IRecordSelectorProps } from "./IRecordSelectorProps"; 4 | import { DropdownOld } from './DropdownOld'; 5 | import { DropdownNew } from './DropdownNew'; 6 | 7 | 8 | export const RecordSelector: React.FunctionComponent = props => { 9 | if (!props.theme) { 10 | return ( 11 | { 16 | props.onChange(option); 17 | }} 18 | 19 | />); 20 | } 21 | 22 | return ( 23 | ); 30 | } 31 | 32 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/img/YearDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/YearDropdown/YearDropdown/img/YearDropdown.png -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/strings/YearDropdown.1031.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Zielspalte 63 | 64 | 65 | Die an dieses Steuerelement gebundene Spalte 66 | 67 | 68 | Jahre zuvor 69 | 70 | 71 | Anzahl der Jahre, die im Dropdown-Menü vor dem aktuellen Jahr hinzugefügt werden 72 | 73 | 74 | Jahre danach 75 | 76 | 77 | Anzahl der Jahre, die im Dropdown-Menü nach dem aktuellen Jahr hinzugefügt werden 78 | 79 | 80 | Standardmonat 81 | 82 | 83 | Standardmonat zur Generierung des Datums, wenn die Zielspalte vom Typ Datum ist 84 | 85 | 86 | Standardtag 87 | 88 | 89 | Standardtag zur Generierung des Datums, wenn die Zielspalte vom Typ Datum ist 90 | 91 | 92 | Jahresauswahl-Dropdown 93 | 94 | 95 | Ein Steuerelement zur Auswahl eines Jahres und Speicherung in einer DateTime-, Ganzzahl- oder Zeichenkettenspalte 96 | 97 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/strings/YearDropdown.1033.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Target column 63 | 64 | 65 | The column bound to this control 66 | 67 | 68 | Years before 69 | 70 | 71 | The number of years to add in the dropdown prior of current year 72 | 73 | 74 | Years after 75 | 76 | 77 | The number of years to add in the dropdown after of current year 78 | 79 | 80 | Default month 81 | 82 | 83 | Default month to generate the date when the target column is of type Date 84 | 85 | 86 | Default day 87 | 88 | 89 | Default day to generate the date when the target column is of type Date 90 | 91 | 92 | Year selection dropdown 93 | 94 | 95 | A control to select a year and store it in DateTime, Whole number or string column 96 | 97 | -------------------------------------------------------------------------------- /YearDropdown/YearDropdown/strings/YearDropdown.1036.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | text/microsoft-resx 51 | 52 | 53 | 2.0 54 | 55 | 56 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 57 | 58 | 59 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 60 | 61 | 62 | Colonne liée 63 | 64 | 65 | La colonne liée à ce controle 66 | 67 | 68 | Années avant 69 | 70 | 71 | Le nombre d'année, avant l'année en cours, à afficher dans la liste déroulante 72 | 73 | 74 | Années après 75 | 76 | 77 | Le nombre d'année, après l'année en cours, à afficher dans la liste déroulante 78 | 79 | 80 | Mois par défaut 81 | 82 | 83 | Mois par défaut utilisé lors du stockage de l'année vers une colonne de type Date 84 | 85 | 86 | Jour par défaut 87 | 88 | 89 | Jour par défaut utilisé lors du stockage de l'année vers une colonne de type Date 90 | 91 | 92 | Sélection d'année 93 | 94 | 95 | Un contrôle en liste déroulante pour sélectionner une année et la stocker sous forme de date, de nombre entier ou de texte 96 | 97 | -------------------------------------------------------------------------------- /YearDropdown/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslintjs from "@eslint/js"; 2 | import microsoftPowerApps from "@microsoft/eslint-plugin-power-apps"; 3 | import pluginPromise from "eslint-plugin-promise"; 4 | import reactPlugin from "eslint-plugin-react"; 5 | import globals from "globals"; 6 | import typescriptEslint from "typescript-eslint"; 7 | 8 | /** @type {import('eslint').Linter.Config[]} */ 9 | export default [ 10 | { 11 | ignores: ["**/generated"], 12 | }, 13 | eslintjs.configs.recommended, 14 | ...typescriptEslint.configs.recommendedTypeChecked, 15 | ...typescriptEslint.configs.stylisticTypeChecked, 16 | pluginPromise.configs["flat/recommended"], 17 | microsoftPowerApps.configs.paCheckerHosted, 18 | reactPlugin.configs.flat.recommended, 19 | { 20 | plugins: { 21 | "@microsoft/power-apps": microsoftPowerApps, 22 | }, 23 | 24 | languageOptions: { 25 | globals: { 26 | ...globals.browser, 27 | ComponentFramework: true, 28 | }, 29 | parserOptions: { 30 | ecmaVersion: 2020, 31 | sourceType: "module", 32 | projectService: true, 33 | tsconfigRootDir: import.meta.dirname, 34 | }, 35 | }, 36 | 37 | rules: { 38 | "@typescript-eslint/no-unused-vars": "off", 39 | }, 40 | settings: { 41 | react: { 42 | version: "detect", 43 | }, 44 | }, 45 | }, 46 | ]; 47 | -------------------------------------------------------------------------------- /YearDropdown/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pcf-project", 3 | "version": "1.0.0", 4 | "description": "Project containing your PowerApps Component Framework (PCF) control.", 5 | "scripts": { 6 | "build": "pcf-scripts build", 7 | "clean": "pcf-scripts clean", 8 | "lint": "pcf-scripts lint", 9 | "lint:fix": "pcf-scripts lint fix", 10 | "rebuild": "pcf-scripts rebuild", 11 | "start": "pcf-scripts start", 12 | "start:watch": "pcf-scripts start watch", 13 | "refreshTypes": "pcf-scripts refreshTypes" 14 | }, 15 | "dependencies": { 16 | "@fluentui/react": "^8.29.0", 17 | "@fluentui/react-components": "9.46.2", 18 | "@typescript-eslint/eslint-plugin": "^8.29.0", 19 | "react": "16.14.0", 20 | "react-dom": "16.14.0" 21 | }, 22 | "devDependencies": { 23 | "@eslint/js": "^9.17.0", 24 | "@microsoft/eslint-plugin-power-apps": "^0.2.51", 25 | "@types/powerapps-component-framework": "^1.3.15", 26 | "@types/react": "^16.14.60", 27 | "@types/react-dom": "^16.9.24", 28 | "eslint-plugin-promise": "^7.1.0", 29 | "eslint-plugin-react": "^7.37.2", 30 | "globals": "^15.13.0", 31 | "pcf-scripts": "^1", 32 | "pcf-start": "^1", 33 | "react": "^16.14.0", 34 | "typescript": "^4.9.5", 35 | "typescript-eslint": "^8.18.1" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /YearDropdown/pcfconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "outDir": "./out/controls" 3 | } -------------------------------------------------------------------------------- /YearDropdown/screenshots/YearDropdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MscrmTools/PCF-Controls/f9ad2f81c8dfd06fd27cb390a0e399e8a32999da/YearDropdown/screenshots/YearDropdown.gif -------------------------------------------------------------------------------- /YearDropdown/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json", 3 | "compilerOptions": { 4 | "typeRoots": ["node_modules/@types"], 5 | "module": "es2015", 6 | "moduleResolution": "node" 7 | } 8 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | --------------------------------------------------------------------------------