-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathformAccess.component.tsx
155 lines (135 loc) · 5.15 KB
/
formAccess.component.tsx
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import React, { PropsWithChildren, useCallback, useEffect, useMemo, useState } from "react";
import type { FormOptions, FormSchema, Submission } from "../../interfaces";
import { Card } from "../card/card.component";
import { Form } from "../form/form.component";
import { ChangedSubmission } from "../form/useForm.hook";
import {
AccessRoles,
dataAccessToSubmissions,
FormAccessSchema,
getFormAccess,
shouldUpdate,
SubmissionAccess,
submissionsToDataAccess,
updateSubmissions
} from "./formAccess.utils";
export interface FormAccessProps {
form: Partial<FormSchema>;
roles: any;
onSubmit?: Function;
options?: FormOptions;
}
function useFormAccess({ form: formDefinition, roles, onSubmit, options }: FormAccessProps) {
const form = useMemo(() => getFormAccess(roles), [roles]);
const [submissions, setSubmissions] = useState(() => dataAccessToSubmissions(formDefinition, form));
const onChange = useCallback(
(type: string, submission: Submission<AccessRoles>) => {
updateSubmissions(type, submission, submissions, setSubmissions);
},
[submissions]
);
useEffect(() => {
const input = dataAccessToSubmissions(formDefinition, form);
if (formDefinition?._id) {
if (shouldUpdate("access", submissions.access, input) || shouldUpdate("submissionAccess", submissions.submissionAccess, input)) {
setSubmissions(input);
}
}
}, [formDefinition?._id]);
return {
options,
form,
type: formDefinition.type,
submissions,
onChange,
onSubmit: () => {
onSubmit && onSubmit(submissionsToDataAccess(formDefinition, submissions));
}
};
}
interface NamedFormAccessProps {
name: "access" | "submissionAccess";
form: FormAccessSchema;
submissions: SubmissionAccess;
options: any;
onSubmit: any;
onChange(name: "access" | "submissionAccess", submission: Submission<AccessRoles>): void;
}
function NamedFormAccess({ name, form, submissions, options, onChange, onSubmit, children }: PropsWithChildren<NamedFormAccessProps>) {
const [isValid, setIsValid] = useState(true);
return (
<>
<Form
name={name}
form={form[name]}
submission={submissions[name]}
onChange={({ data, isValid }: ChangedSubmission<AccessRoles>) => {
isValid && onChange(name, { data });
setIsValid(isValid);
}}
options={options}
/>
<button disabled={!isValid} className={"mt-5 btn btn-primary"} onClick={onSubmit}>
Save access
</button>
{children}
<div className={"alert alert-warning mt-5"}>
Elevated permissions allow users to access and modify other user's entities. Assign with caution.
</div>
</>
);
}
export function FormAccess(props: PropsWithChildren<FormAccessProps>) {
const { type, form, submissions, options, onChange, onSubmit } = useFormAccess(props);
return (
<div>
{props.children}
<div className={"flex mb-5"}>
<Card label={"Manage submission access"} className={"flex-1"}>
<NamedFormAccess
name={"submissionAccess"}
form={form}
submissions={submissions}
onChange={onChange}
onSubmit={onSubmit}
options={options}
>
{props.children}
</NamedFormAccess>
</Card>
<div className={"w-1/4 pl-4"}>
<Card label={"About Submission Data Permissions"}>
<p>Submission Data Permissions allow you to control who can create, view, and modify form submission data.</p>
<ul className={"mt-5 pl-7 list-disc"}>
<li className={"pb-2"}>
<strong>Own Permissions</strong> - These permissions apply if the user is the original creator of the submission data and is
listed as the owner of the submission in submission.owner. This allows users to create and edit their own submission data
without seeing other user's data.
</li>
<li>
<strong>All Permissions</strong> - These permissions apply to all submission data regardless of who owns it.
</li>
</ul>
</Card>
</div>
</div>
<div className={"flex mb-5"}>
<Card label={`Manage ${type} definition access`} className={"flex-1"}>
<NamedFormAccess name={"access"} form={form} submissions={submissions} onChange={onChange} onSubmit={onSubmit} options={options}>
{props.children}
</NamedFormAccess>
</Card>
<div className={"w-1/4 pl-4"}>
<Card label={"About Form Definition Access"}>
<p>These permissions allow you to give access to a single form's JSON definition so they can render the form.</p>
<p>Typically you will want to allow all of your roles to be able to Read the form definition.</p>
<p>
Each form also has an owner at <strong>form.owner</strong> which is the user who created the form. In some applications users
are allowed to create their own forms. In those cases it is helpful to have Owner based permissions as well.
</p>
</Card>
</div>
</div>
</div>
);
}