Migrate to a monorepo structure (#2909)
This commit is contained in:
@ -0,0 +1,60 @@
|
||||
import { useCallback, useEffect } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { tokenPairState } from '@/auth/states/tokenPairState';
|
||||
import { useImpersonateMutation } from '~/generated/graphql';
|
||||
|
||||
import { AppPath } from '../../modules/types/AppPath';
|
||||
|
||||
export const ImpersonateEffect = () => {
|
||||
const navigate = useNavigate();
|
||||
const { userId } = useParams();
|
||||
|
||||
const [currentUser, setCurrentUser] = useRecoilState(currentUserState);
|
||||
const setTokenPair = useSetRecoilState(tokenPairState);
|
||||
|
||||
const [impersonate] = useImpersonateMutation();
|
||||
|
||||
const isLogged = useIsLogged();
|
||||
|
||||
const handleImpersonate = useCallback(async () => {
|
||||
if (!isNonEmptyString(userId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const impersonateResult = await impersonate({
|
||||
variables: { userId },
|
||||
});
|
||||
|
||||
if (impersonateResult.errors) {
|
||||
throw impersonateResult.errors;
|
||||
}
|
||||
|
||||
if (!impersonateResult.data?.impersonate) {
|
||||
throw new Error('No impersonate result');
|
||||
}
|
||||
|
||||
setCurrentUser({
|
||||
...impersonateResult.data.impersonate.user,
|
||||
// Todo also set WorkspaceMember
|
||||
});
|
||||
setTokenPair(impersonateResult.data?.impersonate.tokens);
|
||||
|
||||
return impersonateResult.data?.impersonate;
|
||||
}, [userId, impersonate, setCurrentUser, setTokenPair]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLogged && currentUser?.canImpersonate && isNonEmptyString(userId)) {
|
||||
handleImpersonate();
|
||||
} else {
|
||||
// User is not allowed to impersonate or not logged in
|
||||
navigate(AppPath.Index);
|
||||
}
|
||||
}, [userId, currentUser, isLogged, handleImpersonate, navigate]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
@ -0,0 +1,34 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import {
|
||||
PageDecorator,
|
||||
PageDecoratorArgs,
|
||||
} from '~/testing/decorators/PageDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { sleep } from '~/testing/sleep';
|
||||
|
||||
import { ImpersonateEffect } from '../ImpersonateEffect';
|
||||
|
||||
const meta: Meta<PageDecoratorArgs> = {
|
||||
title: 'Pages/Impersonate/Impersonate',
|
||||
component: ImpersonateEffect,
|
||||
decorators: [PageDecorator],
|
||||
args: {
|
||||
routePath: AppPath.Impersonate,
|
||||
routeParams: { ':userId': '1' },
|
||||
},
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof ImpersonateEffect>;
|
||||
|
||||
export const Default: Story = {
|
||||
play: async () => {
|
||||
await sleep(100);
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user