Let's navigate to the 'stories' folder.
In the 'Story.js' file, add a new tab for Story permissions on line 15 like this:
Copy <Tabs defaultActiveKey="details">
<Tab eventKey="details" title="Details"><Dashboard story={story} setSelectedStory={setSelectedStory} setStories={setStories}/></Tab>
<Tab eventKey="permissions" title="Permissions"><StoryPermissions story={story}/></Tab>
</Tabs>
In the Dashboard component, add new state variables and make use of the useAccess hook to see which permissions the user has for changing story elements:
Copy .
.
.
const [estimateAccess, setEstimateAccess] = useState(false)
const [statusAccess, setStatusAccess] = useState(false)
const [assigneeAccess, setAssigneeAccess] = useState(false)
const {story, setSelectedStory, setStories} = props
useAccess(story.id, "EstimateStory", setEstimateAccess)
useAccess(story.id, "ChangeStoryStatus", setStatusAccess)
useAccess(story.id, "ChangeStoryAssignee", setAssigneeAccess)
.
.
.
Now, disable form controls if the user doesn't have the required permissions:
Copy .
.
.
<Form.Group className="mb-3">
<Form.Label>Estimate</Form.Label>
<Form.Control disabled={!estimateAccess} type="number" value={estimate} onChange={handleEstimateChange} onBlur={handleEstimateBlur}/>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Status</Form.Label>
<Form.Select disabled={!statusAccess} value={status} onChange={handleStatusChange}>
<option value="todo">todo</option>
<option value="busy">busy</option>
<option value="done">done</option>
</Form.Select>
</Form.Group>
<Form.Group className="mb-3">
<Form.Label>Assignee</Form.Label>
<Form.Select disabled={!assigneeAccess} value={assignee} onChange={handleAssigneeChange}>
.
.
.
And add the StoryPermissions component to the same file:
Copy function StoryPermissions(props) {
const {story} = props
return <>
<AccessGuard resourceId={story.id} action="ReadStoryPermissions">
<Permissions resourceId={story.id} changeAction="ChangeStoryPermissions"/>
</AccessGuard>
</>
}
In the 'Stories.js' file, wrap the CreateStory button on line 70 in an AccessGuard like this:
Copy selectedStory
? <Story story={selectedStory} setSelectedStory={setSelectedStory} setStories={setStories}/>
: <AccessGuard resourceId={sprintCtx.sprint.id} action="CreateStory">
<CreateStory setStories={setStories}/>
</AccessGuard>
And disable the StoryButton element if the user doesn't have 'ReadStory' permission on the story:
Copy function StoryButton(props) {
const [readAccess, setReadAccess] = useState(false)
useAccess(props.story.id, "ReadStory", setReadAccess)
return <>
<ListGroupItem
disabled={!readAccess}
.
.
.
That's it! You now have a fully permissioned app, congratulations!