Skip to content

Commit

Permalink
remove old-unused API layer functions
Browse files Browse the repository at this point in the history
rename RcraProfile to RcrainfoProfile for clarity

update RcraProfile serializer to allow blank/null RCRAInfo API ID and key, update with RTK query mutation
  • Loading branch information
dpgraham4401 committed Dec 19, 2023
1 parent 986e904 commit 17863e0
Show file tree
Hide file tree
Showing 33 changed files with 275 additions and 293 deletions.
72 changes: 18 additions & 54 deletions client/src/components/RcraProfile/RcraProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,41 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { AxiosError } from 'axios';
import { RcraApiUserBtn } from 'components/Rcrainfo';
import { SyncRcrainfoProfileBtn } from 'components/RcraProfile/SyncRcrainfoProfileBtn';
import { HtForm, HtSpinner } from 'components/UI';
import { useProgressTracker } from 'hooks';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Button, Col, Container, Form, Row, Table } from 'react-bootstrap';
import { useForm } from 'react-hook-form';
import { toast } from 'react-toastify';
import { UserApi } from 'services';
import {
addAlert,
addTask,
getRcraProfile,
RcrainfoProfileState,
updateProfile,
useAppDispatch,
} from 'store';
import { RcrainfoProfileState, useAppDispatch, useUpdateRcrainfoProfileMutation } from 'store';
import { authApi } from 'store/userSlice/user.slice';
import { z } from 'zod';

interface ProfileViewProps {
profile: RcrainfoProfileState;
}

const rcraProfileForm = z.object({
rcraAPIID: z.string().min(36).optional(),
rcraAPIKey: z.string().min(20).optional(),
rcraAPIID: z.string().min(36).optional().or(z.string().nullable()),
rcraAPIKey: z.string().min(20).optional().or(z.string().nullable()),
rcraUsername: z.string().min(8).optional(),
});

type RcraProfileForm = z.infer<typeof rcraProfileForm>;

export function RcraProfile({ profile }: ProfileViewProps) {
const dispatch = useAppDispatch();
const [editable, setEditable] = useState(false);
const [profileLoading, setProfileLoading] = useState(false);
const [taskId, setTaskId] = useState<undefined | string>();
const [updateRcrainfoProfile] = useUpdateRcrainfoProfileMutation();
const { rcraSites, isLoading, ...formValues } = profile;
const dispatch = useAppDispatch();
const { inProgress } = useProgressTracker({
taskId: taskId,
reduxAction: getRcraProfile(),
});

useEffect(() => {
dispatch(authApi.util?.invalidateTags(['rcrainfoProfile']));
}, [inProgress]);

const {
register,
reset,
Expand All @@ -51,20 +46,11 @@ export function RcraProfile({ profile }: ProfileViewProps) {
resolver: zodResolver(rcraProfileForm),
});

/**
* submitting the RcraProfile form (RCRAInfo API ID, Key, username, etc.)
* @param data {ProfileSlice}
*/
/** submitting the RcrainfoProfile form (RCRAInfo API ID, Key, username, etc.)*/
const onSubmit = (data: RcraProfileForm) => {
setProfileLoading(!profileLoading);
setEditable(!editable);
UserApi.updateRcrainfoProfile({ username: profile.user, data: data })
.then((r) => {
dispatch(updateProfile(r.data));
})
.then(() => dispatch(getRcraProfile()))
.then(() => setProfileLoading(!profileLoading))
.catch((error: AxiosError) => toast.error(error.message));
updateRcrainfoProfile({ username: profile.user, data: data });
};

if (profile.isLoading) return <HtSpinner center />;
Expand Down Expand Up @@ -126,10 +112,9 @@ export function RcraProfile({ profile }: ProfileViewProps) {
<>
<Button
className="mx-2"
variant="success"
variant="outline-info"
type="button"
onClick={(event) => {
event.preventDefault();
onClick={() => {
setEditable(!editable);
}}
>
Expand Down Expand Up @@ -191,29 +176,8 @@ export function RcraProfile({ profile }: ProfileViewProps) {
</Table>
)}
</Container>
<div className="mx-1 d-flex flex-row-reverse">
<RcraApiUserBtn
className="mx-2"
variant="primary"
onClick={() => {
UserApi.syncRcrainfoProfile()
.then((response) => {
dispatch(
addTask({
taskId: response.data.taskId,
status: 'PENDING',
taskName: 'Syncing RCRAInfo Profile',
})
);
setTaskId(response.data.taskId);
})
.catch((error: AxiosError) =>
dispatch(addAlert({ message: error.message, type: 'error' }))
);
}}
>
Sync Site Permissions
</RcraApiUserBtn>
<div className="m-1 d-flex flex-row-reverse">
<SyncRcrainfoProfileBtn taskId={taskId} setTaskId={setTaskId} />
</div>
</>
);
Expand Down
41 changes: 41 additions & 0 deletions client/src/components/RcraProfile/SyncRcrainfoProfileBtn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { RcraApiUserBtn } from 'components/Rcrainfo';
import React, { useEffect } from 'react';
import { addTask, updateTask, useAppDispatch, useSyncRcrainfoProfileMutation } from 'store';

interface SyncRcrainfoProfileBtnProps {
taskId?: string;
setTaskId: (taskId: string) => void;
}

export function SyncRcrainfoProfileBtn({ taskId, setTaskId }: SyncRcrainfoProfileBtnProps) {
const dispatch = useAppDispatch();
const [syncRcrainfoProfile, { data, error, isLoading }] = useSyncRcrainfoProfileMutation();

useEffect(() => {
if (data) {
dispatch(
addTask({
taskId: data.taskId,
status: 'PENDING',
taskName: 'Syncing RCRAInfo Profile',
})
);
setTaskId(data.taskId);
}
if (error) {
dispatch(updateTask({ taskId: taskId, status: 'FAILURE', complete: true }));
}
}, [data, error, isLoading]);

return (
<RcraApiUserBtn
className="mx-2"
variant="primary"
onClick={() => {
syncRcrainfoProfile();
}}
>
Sync Site Permissions
</RcraApiUserBtn>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, ButtonProps } from 'react-bootstrap';
import { selectHaztrakProfile, useAppSelector } from 'store';
import { useGetProfileQuery } from 'store';

interface HtApiUserBtnProps extends ButtonProps {}

Expand All @@ -9,8 +9,10 @@ interface HtApiUserBtnProps extends ButtonProps {}
* @constructor
*/
export function RcraApiUserBtn({ children, ...props }: HtApiUserBtnProps) {
const profile = useAppSelector(selectHaztrakProfile);
const active = !props.disabled && profile.org?.rcrainfoIntegrated;
const { rcrainfoIntegrated } = useGetProfileQuery(undefined, {
selectFromResult: ({ data }) => ({ rcrainfoIntegrated: data?.org?.rcrainfoIntegrated }),
});
const active = !props.disabled && rcrainfoIntegrated;

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion client/src/features/Profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function Profile(): ReactElement {
</Col>
<Col xs={12} lg={6} className="my-3">
<HtCard title="My Organization" className="h-100 my-2">
<HtCard.Body>{profile.org && <UserOrg profile={profile} />}</HtCard.Body>
<HtCard.Body>{profile && <UserOrg profile={profile} />}</HtCard.Body>
</HtCard>
</Col>
</Row>
Expand Down
59 changes: 0 additions & 59 deletions client/src/services/APIs/UserApi.ts

This file was deleted.

1 change: 0 additions & 1 deletion client/src/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export { htApi } from 'services/APIs/htApi';
export { UserApi } from 'services/APIs/UserApi';
export { manifest } from 'services/manifest/manifest';
3 changes: 2 additions & 1 deletion client/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const {
useGetProfileQuery,
useGetRcrainfoProfileQuery,
useUpdateUserMutation,
useUpdateRcrainfoProfileMutation,
useSyncRcrainfoProfileMutation,
} = authApi;

// Authentication Slice
Expand All @@ -43,7 +45,6 @@ export {

// Profile Slice
export {
getRcraProfile,
selectRcrainfoSites,
selectRcraProfile,
siteByEpaIdSelector,
Expand Down
2 changes: 1 addition & 1 deletion client/src/store/profileSlice/profile.slice.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* RcraProfile tests
* RcrainfoProfile tests
*/
import '@testing-library/jest-dom';
import { screen } from '@testing-library/react';
Expand Down
58 changes: 4 additions & 54 deletions client/src/store/profileSlice/profile.slice.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/**
* A user's RcraProfile slice encapsulates our logic related what actions and data a user
* A user's RcrainfoProfile slice encapsulates our logic related what actions and data a user
* has access to for each EPA site ID.
*/
import { createAsyncThunk, createSelector, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { createSelector, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { HaztrakSite } from 'components/HaztrakSite';
import { RcraSite } from 'components/RcraSite';
import { UserApi } from 'services';
import { RootState } from 'store';

/**The user's RCRAInfo account data stored in the Redux store*/
Expand Down Expand Up @@ -64,7 +63,7 @@ export interface RcrainfoSitePermissions {
myRCRAid: string;
}

/**initial, state of a user's RcraProfile.*/
/**initial, state of a user's RcrainfoProfile.*/
const initialState: ProfileSlice = {
user: undefined,
rcrainfoProfile: undefined,
Expand All @@ -73,31 +72,6 @@ const initialState: ProfileSlice = {
error: undefined,
};

/**Retrieves a user's RcrainfoProfile, if it exists, from the server.*/
export const getRcraProfile = createAsyncThunk<ProfileSlice>(
'profile/getRcrainfoProfile',
async (arg, thunkAPI) => {
const state = thunkAPI.getState() as RootState;
const username = state.auth.user?.username;
if (!username) {
throw new Error('User is not logged in');
}
const { data } = await UserApi.getRcrainfoProfile(username);
const { rcraSites, ...rest } = data;
return {
rcrainfoProfile: {
...rest,
rcraSites: rcraSites?.reduce((obj, site) => {
return {
...obj,
[site.epaSiteId]: { epaSiteId: site.epaSiteId, permissions: site.permissions },
};
}, {}),
},
} as ProfileSlice;
}
);

const profileSlice = createSlice({
name: 'profile',
initialState,
Expand All @@ -109,30 +83,6 @@ const profileSlice = createSlice({
};
},
},
extraReducers: (builder) => {
builder
.addCase(getRcraProfile.pending, (state) => {
return {
...state,
loading: true,
error: undefined,
};
})
.addCase(getRcraProfile.fulfilled, (state, action) => {
return {
...state,
...action.payload,
loading: false,
error: undefined,
};
})
.addCase(getRcraProfile.rejected, (state, action) => {
state.loading = false;
// @ts-ignore
state.error = action.payload.error;
return state;
});
},
});

/** Retrieve a Haztrak site from the users Profile by the site's EPA ID number */
Expand Down Expand Up @@ -183,7 +133,7 @@ export const selectRcrainfoSites = createSelector(
}
);

/** Retrieve a user's RcraProfile from the Redux store. */
/** Retrieve a user's RcrainfoProfile from the Redux store. */
export const selectRcraProfile = createSelector(
(state: RootState) => state,
(state: RootState) => state.profile.rcrainfoProfile
Expand Down
Loading

0 comments on commit 17863e0

Please sign in to comment.