Skip to content

Commit

Permalink
ORV2-2571, 2572, 2573 Credit Account - API split integration (#1522)
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnan-aot authored Aug 1, 2024
1 parent 1e4a476 commit a166812
Show file tree
Hide file tree
Showing 21 changed files with 781 additions and 519 deletions.
2 changes: 1 addition & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const SnackBarContext = createContext({
});

const App = () => {
const queryClient = new QueryClient();
const [queryClient] = useState(() => new QueryClient());

// Globally used SnackBar component
const [snackBar, setSnackBar] = useState<SnackBarOptions>({
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/common/authentication/PermissionMatrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const MANAGE_PROFILE = {
* Company Information tab
*/
VIEW_COMPANY_INFORMATION: {
allowedBCeIDAuthGroups: [CA],
allowedBCeIDAuthGroups: ALL_BCeID_GROUPS,
allowedIDIRAuthGroups: [PC, SA, FIN, CTPO, HQA],
},
EDIT_COMPANY_INFORMATION: {
Expand Down Expand Up @@ -508,6 +508,7 @@ export const usePermissionMatrix = ({
isAllowed = Boolean(
currentUserAuthGroup &&
allowedIDIRAuthGroups?.includes(currentUserAuthGroup),

);
} else {
currentUserAuthGroup = userDetails?.userAuthGroup;
Expand Down
72 changes: 41 additions & 31 deletions frontend/src/common/components/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,20 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars } from "@fortawesome/free-solid-svg-icons";

import "./Header.scss";
import { DoesUserHaveRoleWithContext } from "../../authentication/util";
import { Brand } from "./components/Brand";
import { UserSection } from "./components/UserSection";
import { getLoginUsernameFromSession } from "../../apiManager/httpRequestHandler";
import { SearchButton } from "./components/SearchButton";
import { SearchFilter } from "./components/SearchFilter";
import { IDPS } from "../../types/idp";
import OnRouteBCContext from "../../authentication/OnRouteBCContext";
import { ROLES, UserRolesType } from "../../authentication/types";
import { Nullable } from "../../types/common";
import { canViewSettingsTab } from "../../../features/settings/helpers/permissions";
import {
APPLICATIONS_ROUTES,
PROFILE_ROUTES,
SETTINGS_ROUTES,
VEHICLES_ROUTES,
} from "../../../routes/constants";
import { RenderIf } from "../reusable/RenderIf";

const getEnv = () => {
const env =
Expand All @@ -46,11 +43,9 @@ const getEnv = () => {
const Navbar = ({
isAuthenticated,
isMobile = false,
userRoles,
}: {
isAuthenticated: boolean;
isMobile?: boolean;
userRoles?: Nullable<UserRolesType[]>;
}) => {
const navbarClassName = isMobile ? "mobile" : "normal";
return (
Expand All @@ -59,28 +54,44 @@ const Navbar = ({
<ul>
{isAuthenticated && (
<>
{DoesUserHaveRoleWithContext(ROLES.WRITE_PERMIT) && (
<li>
<NavLink to={APPLICATIONS_ROUTES.BASE}>Permits</NavLink>
</li>
)}
{DoesUserHaveRoleWithContext(ROLES.READ_VEHICLE) && (
<li>
<NavLink to={VEHICLES_ROUTES.MANAGE}>
Vehicle Inventory
</NavLink>
</li>
)}
{DoesUserHaveRoleWithContext(ROLES.READ_ORG) && (
<li>
<NavLink to={PROFILE_ROUTES.MANAGE}>Profile</NavLink>
</li>
)}
{canViewSettingsTab(userRoles) && (
<li>
<NavLink to={SETTINGS_ROUTES.MANAGE}>Settings</NavLink>
</li>
)}
<RenderIf
component={
<li>
<NavLink to={APPLICATIONS_ROUTES.BASE}>Permits</NavLink>
</li>
}
permissionMatrixFeatureKey="MANAGE_PERMITS"
permissionMatrixFunctionKey="VIEW_PERMITS_SCREEN"
/>
<RenderIf
component={
<li>
<NavLink to={VEHICLES_ROUTES.MANAGE}>
Vehicle Inventory
</NavLink>
</li>
}
permissionMatrixFeatureKey="MANAGE_VEHICLE_INVENTORY"
permissionMatrixFunctionKey="VIEW_VEHICLE_INVENTORY_SCREEN"
/>
<RenderIf
component={
<li>
<NavLink to={PROFILE_ROUTES.MANAGE}>Profile</NavLink>
</li>
}
permissionMatrixFeatureKey="MANAGE_PROFILE"
permissionMatrixFunctionKey="VIEW_COMPANY_INFORMATION"
/>
<RenderIf
component={
<li>
<NavLink to={SETTINGS_ROUTES.MANAGE}>Settings</NavLink>
</li>
}
permissionMatrixFeatureKey="MANAGE_SETTINGS"
permissionMatrixFunctionKey="VIEW_SPECIAL_AUTHORIZATIONS"
/>
</>
)}
</ul>
Expand Down Expand Up @@ -118,7 +129,7 @@ export const Header = () => {
const [menuOpen, setMenuOpen] = useState(false);
const [filterOpen, setFilterOpen] = useState(false);
const { isAuthenticated, user } = useAuth();
const { companyId, userRoles } = useContext(OnRouteBCContext);
const { companyId } = useContext(OnRouteBCContext);

const username = getLoginUsernameFromSession();
const isIdir = user?.profile?.identity_provider === IDPS.IDIR;
Expand Down Expand Up @@ -154,13 +165,12 @@ export const Header = () => {
</div>
</header>
{shouldDisplayNavBar && (
<Navbar isAuthenticated={isAuthenticated} userRoles={userRoles} />
<Navbar isAuthenticated={isAuthenticated} />
)}
{shouldDisplayNavBar && menuOpen ? (
<Navbar
isAuthenticated={isAuthenticated}
isMobile={true}
userRoles={userRoles}
/>
) : null}
{filterOpen ? <SearchFilter closeFilter={toggleFilter} /> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import { BCEID_PROFILE_TABS } from "../../types/manageProfile.d";
import { ERROR_ROUTES, PROFILE_ROUTES } from "../../../../routes/constants";
import { getDefaultRequiredVal } from "../../../../common/helpers/util";
import { SpecialAuthorizations } from "../../../settings/pages/SpecialAuthorizations/SpecialAuthorizations";
import { CreditAccount } from "../../../settings/pages/CreditAccount";
import { useGetCreditAccountQuery } from "../../../settings/hooks/creditAccount";
import { ViewCreditAccount } from "../../../settings/pages/ViewCreditAccount";
import { useGetCreditAccountMetadataQuery } from "../../../settings/hooks/creditAccount";
import { useFeatureFlagsQuery } from "../../../../common/hooks/hooks";
import { CREDIT_ACCOUNT_USER_TYPE } from "../../../settings/types/creditAccount";
import {
canViewSpecialAuthorizations,
canViewCreditAccountTab,
} from "../../../settings/helpers/permissions";
CREDIT_ACCOUNT_USER_TYPE,
CreditAccountMetadata,
} from "../../../settings/types/creditAccount";
import { canViewSpecialAuthorizations } from "../../../settings/helpers/permissions";
import { usePermissionMatrix } from "../../../../common/authentication/PermissionMatrix";

interface ProfileDashboardTab {
label: string;
Expand Down Expand Up @@ -66,31 +67,29 @@ export const ManageProfilesDashboard = React.memo(() => {
idirUserDetails,
userDetails,
} = useContext(OnRouteBCContext);

const companyId = getDefaultRequiredVal(0, companyIdFromContext);
const { data: creditAccount } = useGetCreditAccountQuery(companyId);
const { data: creditAccountMetadata } =
useGetCreditAccountMetadataQuery(companyId);
const { data: featureFlags } = useFeatureFlagsQuery();
const populatedUserRoles = getDefaultRequiredVal([], userRoles);
const isStaffActingAsCompany = Boolean(idirUserDetails?.userAuthGroup);
const isBCeIDAdmin = isBCeIDOrgAdmin(populatedUserRoles);
const shouldAllowUserManagement = isBCeIDAdmin || isStaffActingAsCompany;
const showSpecialAuth = !isStaffActingAsCompany && canViewSpecialAuthorizations(
userRoles,
userDetails?.userAuthGroup,
) && featureFlags?.["LOA"] === "ENABLED";

const creditAccountHolder = creditAccount?.creditAccountUsers.find(
(user) => user.userType === CREDIT_ACCOUNT_USER_TYPE.HOLDER,
);
const isCreditAccountHolder = companyId === creditAccountHolder?.companyId;

const showCreditAccountTab = Boolean(
canViewCreditAccountTab(userRoles) &&
creditAccount &&
companyId &&
isCreditAccountHolder &&
featureFlags?.["CREDIT-ACCOUNT"] === "ENABLED",
);
const showSpecialAuth =
!isStaffActingAsCompany &&
canViewSpecialAuthorizations(userRoles, userDetails?.userAuthGroup) &&
featureFlags?.["LOA"] === "ENABLED";

const isCreditAccountHolder =
creditAccountMetadata?.userType === CREDIT_ACCOUNT_USER_TYPE.HOLDER;

const showCreditAccountTab = usePermissionMatrix({
featureFlag: "CREDIT-ACCOUNT",
permissionMatrixFeatureKey: "MANAGE_SETTINGS",
permissionMatrixFunctionKey: "VIEW_CREDIT_ACCOUNT_TAB",
additionalConditionToCheck: () => isCreditAccountHolder,
});

const { state: stateFromNavigation } = useLocation();

Expand All @@ -100,31 +99,42 @@ export const ManageProfilesDashboard = React.memo(() => {
component: <CompanyInfo companyInfoData={companyInfoData} />,
componentKey: BCEID_PROFILE_TABS.COMPANY_INFORMATION,
},
!isStaffActingAsCompany ? {
label: "My Information",
component: <MyInfo />,
componentKey: BCEID_PROFILE_TABS.MY_INFORMATION,
} : null,
shouldAllowUserManagement ? {
label: "Add / Manage Users",
component: <UserManagement />,
componentKey: BCEID_PROFILE_TABS.USER_MANAGEMENT,
} : null,
showSpecialAuth && companyId ? {
label: "Special Authorizations",
component: (
<SpecialAuthorizations
companyId={companyId}
/>
),
componentKey: BCEID_PROFILE_TABS.SPECIAL_AUTH,
} : null,
showCreditAccountTab ? {
label: "Credit Account",
component: <CreditAccount companyId={companyId} />,
componentKey: BCEID_PROFILE_TABS.CREDIT_ACCOUNT,
} : null,
].filter(tab => Boolean(tab)) as ProfileDashboardTab[];
!isStaffActingAsCompany
? {
label: "My Information",
component: <MyInfo />,
componentKey: BCEID_PROFILE_TABS.MY_INFORMATION,
}
: null,
shouldAllowUserManagement
? {
label: "Add / Manage Users",
component: <UserManagement />,
componentKey: BCEID_PROFILE_TABS.USER_MANAGEMENT,
}
: null,
showSpecialAuth && companyId
? {
label: "Special Authorizations",
component: <SpecialAuthorizations companyId={companyId} />,
componentKey: BCEID_PROFILE_TABS.SPECIAL_AUTH,
}
: null,
showCreditAccountTab
? {
label: "Credit Account",
component: (
<ViewCreditAccount
companyId={companyId}
creditAccountMetadata={
creditAccountMetadata as CreditAccountMetadata
}
/>
),
componentKey: BCEID_PROFILE_TABS.CREDIT_ACCOUNT,
}
: null,
].filter((tab) => Boolean(tab)) as ProfileDashboardTab[];

const getSelectedTabFromNavigation = (): number => {
const tabIndex = tabs.findIndex(
Expand Down Expand Up @@ -160,7 +170,8 @@ export const ManageProfilesDashboard = React.memo(() => {
}

if (isError) {
const isUnauthorized = error instanceof AxiosError && error.response?.status == 401;
const isUnauthorized =
error instanceof AxiosError && error.response?.status == 401;
return isUnauthorized ? (
<Navigate to={ERROR_ROUTES.UNAUTHORIZED} />
) : (
Expand Down
63 changes: 62 additions & 1 deletion frontend/src/features/settings/apiManager/creditAccount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {
CreditAccountData,
CreditAccountLimitData,
CreditAccountLimitType,
CreditAccountMetadata,
CreditAccountStatusType,
CreditAccountUser,
} from "../types/creditAccount";
import { CREDIT_ACCOUNT_API_ROUTES } from "../apiManager/endpoints/endpoints";
import {
Expand All @@ -28,15 +31,29 @@ export const createCreditAccount = async (data: {
);
};

/**
* Get credit account information for related to the given company ID
* @returns Credit account information for the company
*/
export const getCreditAccountMetadata = async (
companyId: number,
): Promise<CreditAccountMetadata> => {
const response = await httpGETRequest(
CREDIT_ACCOUNT_API_ROUTES.GET_CREDIT_ACCOUNT_META_DATA(companyId),
);
return response.data;
};

/**
* Get credit account information for related to the given company ID
* @returns Credit account information for the company
*/
export const getCreditAccount = async (
companyId: number,
creditAccountId: number,
): Promise<CreditAccountData> => {
const response = await httpGETRequest(
CREDIT_ACCOUNT_API_ROUTES.GET_CREDIT_ACCOUNT(companyId),
CREDIT_ACCOUNT_API_ROUTES.GET_CREDIT_ACCOUNT(companyId, creditAccountId),
);
return response.data;
};
Expand All @@ -58,9 +75,53 @@ export const getCreditAccountUsers = async (data: {
creditAccountId,
),
);
return response.data as CreditAccountUser[];
};

/**
* Get credit account users for the given credit account ID
* @param companyId Identifier of the company with which the credit Account is associated
* @param creditAccountId Identifier of the credit account to retrieve
* @returns List of credit account users for the credit account
*/
export const getCreditAccountHistory = async ({
companyId,
creditAccountId,
}: {
companyId: number;
creditAccountId: number;
}) => {
const response = await httpGETRequest(
CREDIT_ACCOUNT_API_ROUTES.GET_CREDIT_ACCOUNT_HISTORY(
companyId,
creditAccountId,
),
);
return response.data;
};

/**
* Get credit account users for the given credit account ID
* @param companyId Identifier of the company with which the credit Account is associated
* @param creditAccountId Identifier of the credit account to retrieve
* @returns List of credit account users for the credit account
*/
export const getCreditAccountLimits = async ({
companyId,
creditAccountId,
}: {
companyId: number;
creditAccountId: number;
}) => {
const response = await httpGETRequest(
CREDIT_ACCOUNT_API_ROUTES.GET_CREDIT_ACCOUNT_LIMITS(
companyId,
creditAccountId,
),
);
return response.data as CreditAccountLimitData;
};

/**
* Add a user to credit account
* @param companyId Identifier of the company with which the credit Account is associated
Expand Down
Loading

0 comments on commit a166812

Please sign in to comment.