Fix invite user dialog create people + connection prepend edge
Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<6067ce11fa959cba895d2b10862592de>>
|
* @generated SignedSource<<37b59716fa1aba5ed805ce03278ce01d>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -111,13 +111,7 @@ return {
|
|||||||
"kind": "RequiredField",
|
"kind": "RequiredField",
|
||||||
"field": {
|
"field": {
|
||||||
"alias": "invitations",
|
"alias": "invitations",
|
||||||
"args": [
|
"args": null,
|
||||||
{
|
|
||||||
"kind": "Variable",
|
|
||||||
"name": "orderBy",
|
|
||||||
"variableName": "order"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"concreteType": "InvitationConnection",
|
"concreteType": "InvitationConnection",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "__InvitationListFragment_invitations_connection",
|
"name": "__InvitationListFragment_invitations_connection",
|
||||||
@@ -239,6 +233,6 @@ return {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "837e567be489574a7f0350e26a8e5454";
|
(node as any).hash = "6a1b77bc8b0e5f345de9865ec78ef7e9";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<6d84f6b0d10bbae09a14ecc5d84c2814>>
|
* @generated SignedSource<<26a05edf635e281469d5498e24879e00>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -355,9 +355,7 @@ return {
|
|||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": (v13/*: any*/),
|
"args": (v13/*: any*/),
|
||||||
"filters": [
|
"filters": [],
|
||||||
"orderBy"
|
|
||||||
],
|
|
||||||
"handle": "connection",
|
"handle": "connection",
|
||||||
"key": "InvitationListFragment_invitations",
|
"key": "InvitationListFragment_invitations",
|
||||||
"kind": "LinkedHandle",
|
"kind": "LinkedHandle",
|
||||||
@@ -383,6 +381,6 @@ return {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "837e567be489574a7f0350e26a8e5454";
|
(node as any).hash = "6a1b77bc8b0e5f345de9865ec78ef7e9";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<438f2d019c7a08242f35c048016a97e1>>
|
* @generated SignedSource<<14b3e1990be5f8333046dffcada56516>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
||||||
export type InviteMemberInput = {
|
export type InviteMemberInput = {
|
||||||
createPeople: boolean;
|
|
||||||
email: string;
|
email: string;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<5854e660d90c68e5ec01199e55c42a41>>
|
* @generated SignedSource<<70828342a675d5b198c87a4a00455155>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -197,10 +197,7 @@ v17 = {
|
|||||||
"storageKey": null
|
"storageKey": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
};
|
||||||
v18 = [
|
|
||||||
"orderBy"
|
|
||||||
];
|
|
||||||
return {
|
return {
|
||||||
"fragment": {
|
"fragment": {
|
||||||
"argumentDefinitions": (v0/*: any*/),
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
@@ -407,7 +404,9 @@ return {
|
|||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": (v6/*: any*/),
|
"args": (v6/*: any*/),
|
||||||
"filters": (v18/*: any*/),
|
"filters": [
|
||||||
|
"orderBy"
|
||||||
|
],
|
||||||
"handle": "connection",
|
"handle": "connection",
|
||||||
"key": "MemberListFragment_members",
|
"key": "MemberListFragment_members",
|
||||||
"kind": "LinkedHandle",
|
"kind": "LinkedHandle",
|
||||||
@@ -493,7 +492,7 @@ return {
|
|||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": (v6/*: any*/),
|
"args": (v6/*: any*/),
|
||||||
"filters": (v18/*: any*/),
|
"filters": [],
|
||||||
"handle": "connection",
|
"handle": "connection",
|
||||||
"key": "InvitationListFragment_invitations",
|
"key": "InvitationListFragment_invitations",
|
||||||
"kind": "LinkedHandle",
|
"kind": "LinkedHandle",
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const fragment = graphql`
|
|||||||
before: $before
|
before: $before
|
||||||
orderBy: $order
|
orderBy: $order
|
||||||
)
|
)
|
||||||
@connection(key: "InvitationListFragment_invitations")
|
@connection(key: "InvitationListFragment_invitations", filters: [])
|
||||||
@required(action: THROW) {
|
@required(action: THROW) {
|
||||||
__id
|
__id
|
||||||
totalCount
|
totalCount
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {
|
|||||||
Option,
|
Option,
|
||||||
DialogFooter,
|
DialogFooter,
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
|
||||||
useDialogRef,
|
useDialogRef,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { Controller } from "react-hook-form";
|
import { Controller } from "react-hook-form";
|
||||||
@@ -57,7 +56,6 @@ const schema = z.object({
|
|||||||
role: z
|
role: z
|
||||||
.enum(["OWNER", "ADMIN", "FULL", "VIEWER", "AUDITOR", "EMPLOYEE"])
|
.enum(["OWNER", "ADMIN", "FULL", "VIEWER", "AUDITOR", "EMPLOYEE"])
|
||||||
.default("VIEWER"),
|
.default("VIEWER"),
|
||||||
createPeople: z.boolean().default(false),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
type InviteUserDialogProps = PropsWithChildren<{
|
type InviteUserDialogProps = PropsWithChildren<{
|
||||||
@@ -85,13 +83,14 @@ export function InviteUserDialog(props: InviteUserDialogProps) {
|
|||||||
|
|
||||||
const { register, handleSubmit, formState, reset, control } =
|
const { register, handleSubmit, formState, reset, control } =
|
||||||
useFormWithSchema(schema, {
|
useFormWithSchema(schema, {
|
||||||
defaultValues: { role: "VIEWER", createPeople: false },
|
defaultValues: { role: "VIEWER" },
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSubmit = handleSubmit((data) => {
|
const onSubmit = handleSubmit((data) => {
|
||||||
const connectionId = ConnectionHandler.getConnectionID(
|
const connectionId = ConnectionHandler.getConnectionID(
|
||||||
organizationId,
|
organizationId,
|
||||||
"InvitationListFragment_invitations",
|
"InvitationListFragment_invitations",
|
||||||
|
{},
|
||||||
);
|
);
|
||||||
inviteUser({
|
inviteUser({
|
||||||
variables: {
|
variables: {
|
||||||
@@ -100,7 +99,6 @@ export function InviteUserDialog(props: InviteUserDialogProps) {
|
|||||||
email: data.email,
|
email: data.email,
|
||||||
fullName: data.fullName,
|
fullName: data.fullName,
|
||||||
role: data.role,
|
role: data.role,
|
||||||
createPeople: data.createPeople,
|
|
||||||
},
|
},
|
||||||
connections: [connectionId],
|
connections: [connectionId],
|
||||||
},
|
},
|
||||||
@@ -189,33 +187,6 @@ export function InviteUserDialog(props: InviteUserDialogProps) {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="flex items-center space-x-3">
|
|
||||||
<Controller
|
|
||||||
name="createPeople"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<>
|
|
||||||
<Checkbox
|
|
||||||
checked={field.value ?? false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
className="text-sm font-medium cursor-pointer"
|
|
||||||
onClick={() => field.onChange(!field.value)}
|
|
||||||
>
|
|
||||||
{__("Create people record")}
|
|
||||||
</label>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-txt-secondary ml-7">
|
|
||||||
{__(
|
|
||||||
"Creates a people record for this user in addition to the user account",
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button type="submit" disabled={isInviting}>
|
<Button type="submit" disabled={isInviting}>
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ type (
|
|||||||
AttributeRole *string
|
AttributeRole *string
|
||||||
AutoSignupEnabled *bool
|
AutoSignupEnabled *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateInvitationRequest struct {
|
||||||
|
Email mail.Addr
|
||||||
|
FullName string
|
||||||
|
Role coredata.MembershipRole
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -350,9 +356,7 @@ func (s *OrganizationService) CountInvitations(
|
|||||||
func (s *OrganizationService) InviteMember(
|
func (s *OrganizationService) InviteMember(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
emailAddress mail.Addr,
|
req *CreateInvitationRequest,
|
||||||
fullName string,
|
|
||||||
role coredata.MembershipRole,
|
|
||||||
) (*coredata.Invitation, error) {
|
) (*coredata.Invitation, error) {
|
||||||
var (
|
var (
|
||||||
scope = coredata.NewScopeFromObjectID(organizationID)
|
scope = coredata.NewScopeFromObjectID(organizationID)
|
||||||
@@ -360,9 +364,9 @@ func (s *OrganizationService) InviteMember(
|
|||||||
invitation = &coredata.Invitation{
|
invitation = &coredata.Invitation{
|
||||||
ID: gid.New(organizationID.TenantID(), coredata.InvitationEntityType),
|
ID: gid.New(organizationID.TenantID(), coredata.InvitationEntityType),
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
Email: emailAddress,
|
Email: req.Email,
|
||||||
FullName: fullName,
|
FullName: req.FullName,
|
||||||
Role: role,
|
Role: req.Role,
|
||||||
Status: coredata.InvitationStatusPending,
|
Status: coredata.InvitationStatusPending,
|
||||||
ExpiresAt: now.Add(s.invitationTokenValidity),
|
ExpiresAt: now.Add(s.invitationTokenValidity),
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
@@ -383,7 +387,7 @@ func (s *OrganizationService) InviteMember(
|
|||||||
}
|
}
|
||||||
|
|
||||||
identity := &coredata.Identity{}
|
identity := &coredata.Identity{}
|
||||||
err = identity.LoadByEmail(ctx, tx, emailAddress)
|
err = identity.LoadByEmail(ctx, tx, invitation.Email)
|
||||||
if err != nil && err != coredata.ErrResourceNotFound {
|
if err != nil && err != coredata.ErrResourceNotFound {
|
||||||
return fmt.Errorf("cannot load identity: %w", err)
|
return fmt.Errorf("cannot load identity: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -608,7 +608,6 @@ input InviteMemberInput {
|
|||||||
email: EmailAddr!
|
email: EmailAddr!
|
||||||
fullName: String!
|
fullName: String!
|
||||||
role: MembershipRole!
|
role: MembershipRole!
|
||||||
createPeople: Boolean!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateMembershipInput {
|
input UpdateMembershipInput {
|
||||||
|
|||||||
@@ -2615,7 +2615,6 @@ input InviteMemberInput {
|
|||||||
email: EmailAddr!
|
email: EmailAddr!
|
||||||
fullName: String!
|
fullName: String!
|
||||||
role: MembershipRole!
|
role: MembershipRole!
|
||||||
createPeople: Boolean!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateMembershipInput {
|
input UpdateMembershipInput {
|
||||||
@@ -12795,7 +12794,7 @@ func (ec *executionContext) unmarshalInputInviteMemberInput(ctx context.Context,
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"organizationId", "email", "fullName", "role", "createPeople"}
|
fieldsInOrder := [...]string{"organizationId", "email", "fullName", "role"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -12830,13 +12829,6 @@ func (ec *executionContext) unmarshalInputInviteMemberInput(ctx context.Context,
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.Role = data
|
it.Role = data
|
||||||
case "createPeople":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("createPeople"))
|
|
||||||
data, err := ec.unmarshalNBoolean2bool(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.CreatePeople = data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ type InviteMemberInput struct {
|
|||||||
Email mail.Addr `json:"email"`
|
Email mail.Addr `json:"email"`
|
||||||
FullName string `json:"fullName"`
|
FullName string `json:"fullName"`
|
||||||
Role coredata.MembershipRole `json:"role"`
|
Role coredata.MembershipRole `json:"role"`
|
||||||
CreatePeople bool `json:"createPeople"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type InviteMemberPayload struct {
|
type InviteMemberPayload struct {
|
||||||
|
|||||||
@@ -884,9 +884,11 @@ func (r *mutationResolver) InviteMember(ctx context.Context, input types.InviteM
|
|||||||
invitation, err := r.iam.OrganizationService.InviteMember(
|
invitation, err := r.iam.OrganizationService.InviteMember(
|
||||||
ctx,
|
ctx,
|
||||||
input.OrganizationID,
|
input.OrganizationID,
|
||||||
input.Email,
|
&iam.CreateInvitationRequest{
|
||||||
input.FullName,
|
Email: input.Email,
|
||||||
coredata.MembershipRoleViewer,
|
FullName: input.FullName,
|
||||||
|
Role: input.Role,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var errOrganizationNotFound *iam.ErrOrganizationNotFound
|
var errOrganizationNotFound *iam.ErrOrganizationNotFound
|
||||||
|
|||||||
Reference in New Issue
Block a user