diff --git a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.d.ts.map b/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.d.ts.map deleted file mode 100644 index f9fc2cd34..000000000 --- a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MobilePreviewDeviceTypeSelector.d.ts","sourceRoot":"../../../../src/","sources":["components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAE/D,MAAM,WAAW,qCAAqC;IACpD,kBAAkB,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CAChD;AAED,MAAM,CAAC,OAAO,OAAO,+BAAgC,SAAQ,KAAK,CAAC,SAAS,CACzE,qCAAqC,EAAE,EAAE,CAAC;IAEpC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;CAmBxC"} \ No newline at end of file diff --git a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.css b/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.css deleted file mode 100644 index 74ea6e6be..000000000 --- a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.css +++ /dev/null @@ -1,2 +0,0 @@ -.mobilePreviewDeviceIcon_4e248641{color:#a19f9d;margin:auto;padding:auto;font-size:40px;line-height:50px}.mobilePreviewDeviceIcon_4e248641:hover{cursor:pointer;color:#767676}.navBarItemRight_4e248641{font-size:14px;padding:0;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;height:40px;line-height:40px;position:relative;float:right;margin:0} -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9jb21wb25lbnRzL21vYmlsZVByZXZpZXcvbW9iaWxlUHJldmlld0hlYWRlckJhci9tb2JpbGVQcmV2aWV3RGV2aWNlVHlwZVNlbGVjdG9yL01vYmlsZVByZXZpZXdEZXZpY2VUeXBlU2VsZWN0b3IubW9kdWxlLnNjc3MiLCJub2RlX21vZHVsZXMvb2ZmaWNlLXVpLWZhYnJpYy1yZWFjdC9kaXN0L3Nhc3MvbWl4aW5zL19Db2xvci5NaXhpbnMuTURMMi5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLGtDQ3dNRSxNQUFBLFFEdE1BLE9BQUEsS0FDQSxRQUFBLEtBQ0EsVUFBQSxLQUNBLFlBQUEsS0FMRix3Q0FRSSxPQUFBLFFBQ0EsTUFBQSxRQUtKLDBCQUNFLFVBQUEsS0FDQSxRQUFBLEVBQ0EsbUJBQUEsV0FBQSxXQUFBLFdBQ0EsUUFBQSxNQUNBLE9BQUEsS0FDQSxZQUFBLEtBQ0EsU0FBQSxTQUNBLE1BQUEsTUFDQSxPQUFBIn0= */ \ No newline at end of file diff --git a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts b/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts deleted file mode 100644 index a9f277586..000000000 --- a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare const styles: { - mobilePreviewDeviceIcon: string; - navBarItemRight: string; -}; -export default styles; -//# sourceMappingURL=MobilePreviewDeviceTypeSelector.module.scss.d.ts.map \ No newline at end of file diff --git a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts.map b/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts.map deleted file mode 100644 index 48aabd844..000000000 --- a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"MobilePreviewDeviceTypeSelector.module.scss.d.ts","sourceRoot":"../../../../src/","sources":["components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,MAAM;;;CAGX,CAAC;AAEF,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.js b/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.js deleted file mode 100644 index a8d4eec34..000000000 --- a/samples/react-enhanced-powerapps/temp/workbench-packages/@microsoft_sp-webpart-workbench/lib/components/mobilePreview/mobilePreviewHeaderBar/mobilePreviewDeviceTypeSelector/MobilePreviewDeviceTypeSelector.module.scss.js +++ /dev/null @@ -1,9 +0,0 @@ -/* tslint:disable */ -require("./MobilePreviewDeviceTypeSelector.module.css"); -var styles = { - mobilePreviewDeviceIcon: 'mobilePreviewDeviceIcon_4e248641', - navBarItemRight: 'navBarItemRight_4e248641' -}; -export default styles; -/* tslint:enable */ -//# sourceMappingURL=MobilePreviewDeviceTypeSelector.module.scss.js.map \ No newline at end of file diff --git a/samples/react-questions-and-answers/README.md b/samples/react-questions-and-answers/README.md index 33ec64f34..4bec3c698 100644 --- a/samples/react-questions-and-answers/README.md +++ b/samples/react-questions-and-answers/README.md @@ -78,47 +78,47 @@ Delete a question|Deletes the question (and replies when done by moderator). Ava Follow/Unfollow a Question|Filled envelop if followed & empty envelop if not followed for the current user. Used to drive email notification on questions. Like/Unlike a Question|Filled thumbs if liked & empty thumbs if not. Count should be for all likes on the Question but not including replies. -### Replies +### Replies Feature|Details -------|------- Reply to a Question or Reply| Edit a Reply| -Delete a Reply|Deletes the reply (and replies when done by moderator). Available on Gear icon. -Like/Unlike a Reply|Filled thumbs if liked & empty thumbs if not. +Delete a Reply|Deletes the reply (and replies when done by moderator). Available on Gear icon. +Like/Unlike a Reply|Filled thumbs if liked & empty thumbs if not. Mark/Unmark a Reply as Helpful|Filled star if liked & empty star if not. Count should be for all helpful items on the Reply but not including replies -Mark/Unmark a Reply as Correct Answer|When marked as correct answer a banner will show with “CORRECT ANSWER”. Copy of reply is promoted just below question so that long thread doesn’t have to be viewed for the answer. Unmarking will remove the banner and the copy of reply promoted to the to of the thread. Available on Gear icon. +Mark/Unmark a Reply as Correct Answer|When marked as correct answer a banner will show with “CORRECT ANSWER”. Copy of reply is promoted just below question so that long thread doesn’t have to be viewed for the answer. Unmarking will remove the banner and the copy of reply promoted to the to of the thread. Available on Gear icon. -## User Roles Overview +## User Roles Overview -The Questions web part relies on the standard SharePoint Groups and the permissions they are granted. +The Questions web part relies on the standard SharePoint Groups and the permissions they are granted. Questions Role|SharePoint Group|Details --------------|----------------|------- -Moderator|Site owners|Users in this group are treated as moderators of Questions with additional capabilities and notifications than others outlined below. -Contributor|Site members|Users in this group are treated as “typical” users and considered contributors to questions by default. -Viewer|Site visitors|By default, users in this group can only view questions and replies. -Contributor|Site visitors|Within the web part there is a toggle that allows a Site owner to grant visitors the same capabilities as a site member on questions. When set to ‘Yes’ site visitors are considered contributors to questions. +Moderator|Site owners|Users in this group are treated as moderators of Questions with additional capabilities and notifications than others outlined below. +Contributor|Site members|Users in this group are treated as “typical” users and considered contributors to questions by default. +Viewer|Site visitors|By default, users in this group can only view questions and replies. +Contributor|Site visitors|Within the web part there is a toggle that allows a Site owner to grant visitors the same capabilities as a site member on questions. When set to ‘Yes’ site visitors are considered contributors to questions. -## Features based Questions Role +## Features based Questions Role -The table below shows what features and capabilities a user can perform for each role. Where a feature is dynamic (such as questions entered by others or me) separate line items call out the different behaviors. +The table below shows what features and capabilities a user can perform for each role. Where a feature is dynamic (such as questions entered by others or me) separate line items call out the different behaviors. -Feature|Moderator|Contributor|Viewer +Feature|Moderator|Contributor|Viewer -------|---------|-----------|------ **Questions**||| -Search for a Question|Yes|Yes|Yes -View a list of Questions|Yes|Yes|Yes -Show List of Questions by All, Answered or Open|Yes|Yes|Yes -View a Question and Replies|Yes|Yes|Yes -Ask a Question|Yes|Yes|No -Edit a Question - Entered by me|Yes|Yes|No -Edit a Question - Entered by others|No|No|No -Delete a question - Entered by me with no replies|Yes|Yes|No -Delete a question - Entered by me with replies|Yes|No|No -Delete a question - Entered by others with no replies|Yes|No|No -Delete a question - Entered by others with replies|Yes|No|No -Follow/Unfollow a Question|Yes|Yes|No +Search for a Question|Yes|Yes|Yes +View a list of Questions|Yes|Yes|Yes +Show List of Questions by All, Answered or Open|Yes|Yes|Yes +View a Question and Replies|Yes|Yes|Yes +Ask a Question|Yes|Yes|No +Edit a Question - Entered by me|Yes|Yes|No +Edit a Question - Entered by others|No|No|No +Delete a question - Entered by me with no replies|Yes|Yes|No +Delete a question - Entered by me with replies|Yes|No|No +Delete a question - Entered by others with no replies|Yes|No|No +Delete a question - Entered by others with replies|Yes|No|No +Follow/Unfollow a Question|Yes|Yes|No Like/Unlike a Question|Yes|Yes|No **Replies**||| Reply to a Question or Reply|Yes|Yes|No diff --git a/samples/react-questions-and-answers/config/package-solution.json b/samples/react-questions-and-answers/config/package-solution.json index 29d848e7c..168b714e2 100644 --- a/samples/react-questions-and-answers/config/package-solution.json +++ b/samples/react-questions-and-answers/config/package-solution.json @@ -3,7 +3,7 @@ "solution": { "name": "Questions and Answers", "id": "6feb4c2f-341b-499c-998c-9b2ebd95435c", - "version": "1.0.0.0", + "version": "1.0.1.0", "skipFeatureDeployment": false, "iconPath": "images/Feedback_Icon.png", "includeClientSideAssets": true, diff --git a/samples/react-questions-and-answers/package-lock.json b/samples/react-questions-and-answers/package-lock.json index a96e99da8..e1f97dd1c 100644 --- a/samples/react-questions-and-answers/package-lock.json +++ b/samples/react-questions-and-answers/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-questions-and-answers", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/samples/react-questions-and-answers/package.json b/samples/react-questions-and-answers/package.json index c8b4c7ee9..04abe059f 100644 --- a/samples/react-questions-and-answers/package.json +++ b/samples/react-questions-and-answers/package.json @@ -1,6 +1,6 @@ { "name": "react-questions-and-answers", - "version": "1.0.0", + "version": "1.0.1", "private": true, "engines": { "node": ">=0.10.0" diff --git a/samples/react-questions-and-answers/src/services/permission.service.ts b/samples/react-questions-and-answers/src/services/permission.service.ts index 01c40c2f4..7f759cc7f 100644 --- a/samples/react-questions-and-answers/src/services/permission.service.ts +++ b/samples/react-questions-and-answers/src/services/permission.service.ts @@ -1,6 +1,11 @@ -import { sp, PermissionKind, RoleType } from '@pnp/sp/presets/all'; +import { sp } from '@pnp/sp'; +import "@pnp/sp/webs"; +import "@pnp/sp/site-groups/web"; +import { PermissionKind } from "@pnp/sp/security"; import { BaseService } from './base.service'; import { LogHelper, ListTitles } from 'utilities'; +import { RoleType } from '@pnp/sp/sharing'; +import { _RoleAssignment, _RoleDefinition } from '@pnp/sp/security/types'; export class PermissionService extends BaseService { @@ -10,12 +15,22 @@ export class PermissionService extends BaseService { LogHelper.verbose(this.constructor.name, 'canVisitorsAskQuestions', ''); let canAsk: boolean = false; - debugger; - let visitorGroup = await sp.web.associatedVisitorGroup(); - let perms = await sp.web.lists.getByTitle(this.listTitle).getUserEffectivePermissions(visitorGroup.LoginName); - if(sp.web.hasPermissions(perms, PermissionKind.AddListItems)) { - canAsk = true; + + console.log(visitorGroup.Id); + + let roles = await sp.web.lists.getByTitle(this.listTitle).roleAssignments + .expand('Member', 'RoleDefinitionBindings') + .get(); + + let visitorRole: any = roles.find(r => r.PrincipalId === visitorGroup.Id); + + if(visitorRole) { + for (let def of visitorRole.RoleDefinitionBindings) { + if (sp.web.hasPermissions(def.BasePermissions, PermissionKind.AddListItems)) { + canAsk = true; + } + } } return canAsk;