diff --git a/build.bat b/build.bat index c52bf22..ee9f5d5 100644 --- a/build.bat +++ b/build.bat @@ -2,6 +2,8 @@ SET msbuild="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" +CALL yarn --cwd .\control + if exist ./solution/bin/Release/solution.zip ( %msbuild% ./solution/solution.cdsproj /t:build /p:Configuration=Release ) else ( diff --git a/control/SecurityRoleManager/ControlManifest.Input.xml b/control/SecurityRoleManager/ControlManifest.Input.xml index d1cdf60..9941f69 100644 --- a/control/SecurityRoleManager/ControlManifest.Input.xml +++ b/control/SecurityRoleManager/ControlManifest.Input.xml @@ -1,7 +1,7 @@ + version="1.2.0"> @@ -40,7 +40,7 @@ - + diff --git a/control/SecurityRoleManager/components/app.tsx b/control/SecurityRoleManager/components/app.tsx index d0ceff6..277a604 100644 --- a/control/SecurityRoleManager/components/app.tsx +++ b/control/SecurityRoleManager/components/app.tsx @@ -1,24 +1,24 @@ import * as React from 'react' -import { Row } from './' -import { ResourceStrings } from '../strings' -import { SecurityRoleService } from '../services' -import { SecurityRoleMap, getEntityReference } from '../utilities' import { Spinner, SpinnerSize } from '@fluentui/react/lib/Spinner' import { Stack } from '@fluentui/react/lib/Stack' import { ScrollablePane } from '@fluentui/react/lib/ScrollablePane' +import { Row } from './row' +import { ResourceStrings } from '../strings' +import { SecurityRoleService } from '../services' +import { SecurityRoleMap } from '../utilities' export interface IAppProps { apiDataUrl: string resourceStrings: ResourceStrings - disabled: boolean + etn: string | null + id: string | null } export function App(props: IAppProps) { - const { apiDataUrl, resourceStrings, disabled } = props + const { apiDataUrl, resourceStrings, etn, id } = props + + const securityRoleService = new SecurityRoleService(apiDataUrl, etn!, id!) - const { etn, id } = getEntityReference() - const securityRoleService = new SecurityRoleService(apiDataUrl, etn, id) - const isSupportedEntity = (etn === 'systemuser' || etn === 'team') const isCreated = (!!id) @@ -28,14 +28,20 @@ export function App(props: IAppProps) { // ComponentDidMount React.useEffect(() => { - if (isSupportedEntity && isCreated) { - securityRoleService.getRoleMap() - .then((response: SecurityRoleMap[]) => setRoleMap(response)) - .finally(() => setLoaded(true)) - } else { - setLoaded(true) + async function getData() { + if (isSupportedEntity && isCreated) { + try { + const response = await securityRoleService.getRoleMap() + setRoleMap(response) + } finally { + setLoaded(true) + } + } else { + setLoaded(true) + } } - }, []) + getData() + }, [isCreated]) const hrStyle: React.CSSProperties = { backgroundColor: '#eee', @@ -87,7 +93,6 @@ export function App(props: IAppProps) { {roleMap.map(securityRoleMap => )} diff --git a/control/SecurityRoleManager/components/index.ts b/control/SecurityRoleManager/components/index.ts deleted file mode 100644 index 4c7ccb3..0000000 --- a/control/SecurityRoleManager/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './app' -export * from './row' diff --git a/control/SecurityRoleManager/components/row.tsx b/control/SecurityRoleManager/components/row.tsx index 0b585d7..d7de3e1 100644 --- a/control/SecurityRoleManager/components/row.tsx +++ b/control/SecurityRoleManager/components/row.tsx @@ -7,12 +7,12 @@ import { Stack, IStackProps } from '@fluentui/react/lib/Stack' export interface IRowProps { securityRoleMap: SecurityRoleMap securityRoleService: SecurityRoleService - disabled: boolean } export function Row(props: IRowProps) { - const { securityRoleService, disabled } = props + const { securityRoleService } = props const [securityRoleMap, setSecurityRoleMap] = React.useState(props.securityRoleMap) + const [processing, setProcessing] = React.useState(false) const stackProps: IStackProps = { horizontal: true, @@ -25,20 +25,25 @@ export function Row(props: IRowProps) { if (typeof checked === 'undefined') return try { + setProcessing(true) + if (checked) { await securityRoleService.associateSecurityRole(securityRoleMap.id) } else { await securityRoleService.disassociateSecurityRoles(securityRoleMap.id) } + setSecurityRoleMap({ ...securityRoleMap, isAssigned: !securityRoleMap.isAssigned }) + } finally { + setProcessing(false) } - } + }, } return ( - + ) } diff --git a/control/SecurityRoleManager/index.ts b/control/SecurityRoleManager/index.ts index 868931d..1207df5 100644 --- a/control/SecurityRoleManager/index.ts +++ b/control/SecurityRoleManager/index.ts @@ -1,14 +1,18 @@ import { IInputs, IOutputs } from './generated/ManifestTypes' import * as React from 'react' import * as ReactDOM from 'react-dom' -import { App, IAppProps } from './components' +import { App, IAppProps } from './components/app' import { ResourceStrings } from './strings' export class SecurityRoleManager implements ComponentFramework.StandardControl { private container: HTMLDivElement - public init(context: ComponentFramework.Context, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement) { + public init(context: ComponentFramework.Context, + notifyOutputChanged: () => void, + state: ComponentFramework.Dictionary, + container: HTMLDivElement) { + this.container = container } @@ -22,7 +26,8 @@ export class SecurityRoleManager implements ComponentFramework.StandardControl param.split('=')) - - let result: Record = {} - - qs.forEach(param => result[param[0]] = param[1]) - - return result -} diff --git a/control/componentframework.extensions.d.ts b/control/componentframework.extensions.d.ts new file mode 100644 index 0000000..45cba18 --- /dev/null +++ b/control/componentframework.extensions.d.ts @@ -0,0 +1,9 @@ +declare namespace ComponentFramework { + interface Mode { + contextInfo: { + entityTypeName: string | null + entityId: string | null + entityRecordName: string | null + } + } +} \ No newline at end of file diff --git a/control/featureconfig.json b/control/featureconfig.json new file mode 100644 index 0000000..37d6cd8 --- /dev/null +++ b/control/featureconfig.json @@ -0,0 +1,3 @@ +{ + "pcfAllowCustomWebpack": "on" +} \ No newline at end of file diff --git a/control/package.json b/control/package.json index 3267f87..b444d3b 100644 --- a/control/package.json +++ b/control/package.json @@ -1,12 +1,12 @@ { "name": "d365-pcf-securityrolemanager", - "version": "1.1.0", + "version": "1.2.0", "description": "D365 - PCF - Security Role Manager", "scripts": { "build": "pcf-scripts build", "clean": "pcf-scripts clean", "rebuild": "pcf-scripts rebuild", - "start": "pcf-scripts start" + "start": "pcf-scripts start watch" }, "dependencies": { "@fluentui/react": "^8.9.4", diff --git a/control/webpack.config.js b/control/webpack.config.js new file mode 100644 index 0000000..a79df89 --- /dev/null +++ b/control/webpack.config.js @@ -0,0 +1,3 @@ +module.exports = { + devtool: 'source-map' +} \ No newline at end of file diff --git a/setup.bat b/setup.bat deleted file mode 100644 index 6b85e7d..0000000 --- a/setup.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -CALL yarn --cwd .\control \ No newline at end of file diff --git a/solution/src/Other/Solution.xml b/solution/src/Other/Solution.xml index 542a6bc..e369a99 100644 --- a/solution/src/Other/Solution.xml +++ b/solution/src/Other/Solution.xml @@ -8,7 +8,7 @@ - 1.1.0 + 1.2.0 2