Skip to content

Commit

Permalink
Add graphql query for add and edit analytical framework memebership
Browse files Browse the repository at this point in the history
  • Loading branch information
shreeyash07 committed Jul 19, 2024
1 parent a30b6a5 commit 22acfdd
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 66 deletions.
192 changes: 126 additions & 66 deletions app/views/AnalyticalFramework/UserTable/AddUserModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useMemo, useCallback, useState } from 'react';
import { isDefined } from '@togglecorp/fujs';
import { isDefined, isNotDefined } from '@togglecorp/fujs';
import {
ObjectSchema,
PartialForm,
Expand All @@ -15,35 +15,37 @@ import {
Button,
PendingMessage,
} from '@the-deep/deep-ui';
import { gql, useQuery } from '@apollo/client';
import { gql, useMutation, useQuery } from '@apollo/client';

import { AnalysisFrameworkRolesQuery } from '#generated/types';
import {
AnalysisFrameworkMembersQuery,
AnalysisFrameworkRolesQuery,
AnalysisMembershipAddEditMutation,
AnalysisMembershipAddEditMutationVariables,
BulkAnalysisFrameworkMembershipInputType,
} from '#generated/types';
import NonFieldError from '#components/NonFieldError';
import { useLazyRequest } from '#base/utils/restRequest';
import { Membership } from '#types';
import NewUserSelectInput, { User } from '#components/selections/NewUserSelectInput';
import _ts from '#ts';

import styles from './styles.css';

type Member = Pick<Membership, 'id' | 'member' | 'memberName' | 'role'>;
type AnalysisFrameworkMember = NonNullable<NonNullable<AnalysisFrameworkMembersQuery['analysisFramework']>['members']>[number];
type AnalysisFrameworkRolesType = NonNullable<NonNullable<AnalysisFrameworkRolesQuery>['analysisFrameworkRoles']>[number];

const roleKeySelector = (d: AnalysisFrameworkRolesType) => Number(d.id);
const roleKeySelector = (d: AnalysisFrameworkRolesType) => d.id;
const roleLabelSelector = (d: AnalysisFrameworkRolesType) => d.title;

type FormType = {
id?: number;
member?: string;
role: number;
};
type PartialAnalysisMemembershipForm = PartialForm<
BulkAnalysisFrameworkMembershipInputType & { frameworkId: string}
>

type FormSchema = ObjectSchema<PartialForm<FormType>>;
type FormSchema = ObjectSchema<PartialAnalysisMemembershipForm>;
type FormSchemaFields = ReturnType<FormSchema['fields']>

const schema: FormSchema = {
fields: (value): FormSchemaFields => {
if (isDefined(value?.id)) {
if (isDefined(value?.frameworkId)) {
return ({
member: [],
role: [requiredCondition],
Expand All @@ -56,7 +58,25 @@ const schema: FormSchema = {
},
};

const defaultFormValue: PartialForm<FormType> = {};
const defaultFormValue: PartialAnalysisMemembershipForm = {};

const ANALYSIS_MEMBERSHIP_ADD_EDIT = gql`
mutation AnalysisMembershipAddEdit(
$frameworkId: ID!
$items: [BulkAnalysisFrameworkMembershipInputType!],
){
analysisFramework(id: $frameworkId) {
analysisFrameworkMembershipBulk(
items: $items
) {
result {
id
}
errors
}
}
}
`;

const ANALYSIS_FRAMEWORK_ROLES = gql`
query AnalysisFrameworkRoles {
Expand All @@ -70,18 +90,12 @@ const ANALYSIS_FRAMEWORK_ROLES = gql`
}
`;

interface ValueToSend {
role: number;
member?: number;
framework: number;
}

interface Props {
onModalClose: () => void;
frameworkId: number;
frameworkId: string;
onTableReload: () => void;
isPrivateFramework: boolean;
userValue?: Member;
userValue?: AnalysisFrameworkMember;
}

function AddUserModal(props: Props) {
Expand All @@ -93,15 +107,18 @@ function AddUserModal(props: Props) {
isPrivateFramework,
} = props;

const initialFormValue: PartialForm<FormType> = useMemo(() => {
const initialFormValue: PartialAnalysisMemembershipForm = useMemo(() => {
if (!userValue) {
return defaultFormValue;
}
return ({
...userValue,
member: String(userValue.member),
frameworkId,
id: userValue.id,
role: userValue.role.id,
member: userValue.member.id,
});
}, [userValue]);
}, [userValue, frameworkId]);

const alert = useAlert();

const [
Expand All @@ -120,6 +137,57 @@ function AddUserModal(props: Props) {

const error = getErrorObject(riskyError);

const [
addEditFrameworkMembership,
{
loading: addEditFrameworkMembershipLoading,
},
] = useMutation<AnalysisMembershipAddEditMutation, AnalysisMembershipAddEditMutationVariables>(
ANALYSIS_MEMBERSHIP_ADD_EDIT,
{
onCompleted: (response) => {
if (!response.analysisFramework?.analysisFrameworkMembershipBulk?.result) {
return;
}

const {
result,
} = response.analysisFramework.analysisFrameworkMembershipBulk;

const ok = isDefined(result) && result?.length > 0;

if (ok) {
if (userValue?.id) {
alert.show(
'Successfully updated user to the analytical framework.',
{ variant: 'success' },
);
} else {
alert.show(
'Successfully added user to the analytical framework.',
{ variant: 'success' },
);
}
onTableReload();
onModalClose();
}
},
onError: () => {
if (userValue?.id) {
alert.show(
'Failed to update users to analytical framework.',
{ variant: 'error' },
);
} else {
alert.show(
'Failed to add users to analytical framework.',
{ variant: 'error' },
);
}
},
},
);

const {
data: analysisFrameworkRolesResponse,
loading: analysisFrameworkRolesLoading,
Expand All @@ -134,64 +202,56 @@ function AddUserModal(props: Props) {
)
), [analysisFrameworkRolesResponse, isPrivateFramework]);

const {
pending: pendingAddAction,
trigger: triggerAddFrameworkMember,
} = useLazyRequest<unknown, ValueToSend>({
url: isDefined(userValue)
? `server://framework-memberships/${userValue.id}/`
: 'server://framework-memberships/',
method: isDefined(userValue)
? 'PATCH'
: 'POST',
body: (ctx) => ctx,
onSuccess: () => {
alert.show(
userValue?.id
? 'Successfully updated user permissions.'
: 'Successfully added user to the analytical framework.',
{
variant: 'success',
},
);
onTableReload();
onModalClose();
},
failureMessage: _ts('analyticalFramework.addUser', 'membershipPostFailed'),
});

const handleSubmit = useCallback(
() => {
const submit = createSubmitHandler(
validate,
setError,
(val) => {
const newVal = val.member ? { member: Number(val.member), ...val } : val;
triggerAddFrameworkMember({
...newVal,
framework: frameworkId,
} as ValueToSend);
if (isNotDefined(val.member)) {
addEditFrameworkMembership({ variables: undefined });
} else if (userValue?.id) {
addEditFrameworkMembership({
variables: {
frameworkId,
items: [{
member: val.member,
role: val.role,
id: userValue.id,
}],
},
});
} else {
addEditFrameworkMembership({
variables: {
frameworkId,
items: [{
member: val.member,
role: val.role,
}],
},
});
}
},
);
submit();
},
[setError, validate, triggerAddFrameworkMember, frameworkId],
[setError, validate, addEditFrameworkMembership, frameworkId, userValue?.id],
);

const currentUser = useMemo(() => (userValue
? [
{
id: String(userValue.member),
displayName: userValue.memberName,
// FIXME: Use graphql to fetch details for User
id: userValue.member.id,
displayName: userValue.member.displayName,
firstName: '',
lastName: '',
emailDisplay: '',
},
] : []
), [userValue]);

const pendingRequests = analysisFrameworkRolesLoading;
const pendingRequests = analysisFrameworkRolesLoading || addEditFrameworkMembershipLoading;

return (
<Modal
Expand All @@ -210,19 +270,19 @@ function AddUserModal(props: Props) {
name="submit"
variant="primary"
type="submit"
disabled={pristine || pendingRequests || pendingAddAction}
disabled={pristine || pendingRequests}
onClick={handleSubmit}
>
{_ts('analyticalFramework.addUser', 'submitLabel')}
</Button>
)}
>
{pendingAddAction && (<PendingMessage />)}
{addEditFrameworkMembershipLoading && (<PendingMessage />)}
<NonFieldError error={error} />
<NewUserSelectInput
name="member"
readOnly={isDefined(userValue)}
value={value.member ? String(value.member) : undefined}
value={value.member}
onChange={setFieldValue}
options={userOptions ?? currentUser}
onOptionsChange={setUserOptions}
Expand Down
1 change: 1 addition & 0 deletions app/views/AnalyticalFramework/UserTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const ANALYSIS_FRAMEWORK_MEMBERS = gql`
id
joinedAt
member {
id
displayName
profile {
organization
Expand Down

0 comments on commit 22acfdd

Please sign in to comment.