Skip to content

Commit

Permalink
feat: add QueryClientProvider and enhance routing with accountName pa…
Browse files Browse the repository at this point in the history
…rameter; update mocks and improve navigation consistency
  • Loading branch information
hervedombya committed Jan 10, 2025
1 parent 71338d7 commit e8a0b49
Show file tree
Hide file tree
Showing 13 changed files with 110 additions and 75 deletions.
7 changes: 7 additions & 0 deletions jestSetupAfterEnv.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,10 @@ jest.mock('./src/react/next-architecture/ui/XCoreLibraryProvider', () => {
});

jest.mock('@module-federation/enhanced/runtime', () => {}, { virtual: true });

jest.mock('@scality/module-federation', () => ({
useCurrentApp: () => ({
name: 'zenko-ui',
appHistoryBasePath: '',
}),
}));
11 changes: 11 additions & 0 deletions src/QueryClientProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {
QueryClient,
QueryClientProvider as BaseQueryClientProvider,
} from 'react-query';

export const QueryClientProvider =
BaseQueryClientProvider as React.ComponentType<{
client: QueryClient;
contextSharing?: boolean;
children?: React.ReactNode;
}>;
4 changes: 2 additions & 2 deletions src/react/DataServiceRoleProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const useCurrentAccount = () => {
else if (accountId) return account.id === accountId;
else return true;
});
}, [accountId, JSON.stringify(accounts)]);
}, [accountId, JSON.stringify(accounts), accountName]);

return {
account,
Expand Down Expand Up @@ -153,7 +153,7 @@ const DataServiceRoleProvider = ({
if (role.roleArn) {
assumeRoleMutation.mutate(role.roleArn);
}
}, [role.roleArn, JSON.stringify(accounts), userData?.token]);
}, [role.roleArn, JSON.stringify(accounts), userData?.token, accountName]);

const { getS3Config } = useS3ConfigFromAssumeRoleResult();

Expand Down
25 changes: 18 additions & 7 deletions src/react/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import LocationEditor from './locations/LocationEditor';
import { useBasenameRelativeNavigate } from './ShellHooksContext';
import Workflows from './workflow/Workflows';
import CreateWorkflow from './workflow/CreateWorkflow';
import Objects from './databrowser/objects/Objects';

export const RemoveTrailingSlash = ({ ...rest }) => {
const location = useLocation();
Expand Down Expand Up @@ -186,6 +187,10 @@ function PrivateRoutes() {
path="accounts/:accountName/create-bucket/*"
element={<BucketCreate />}
/>
<Route
path={'accounts/:accountName/buckets/:bucketName/objects'}
element={<Objects />}
/>
<Route
path="accounts/:accountName/data/buckets/*"
element={<DataBrowser />}
Expand Down Expand Up @@ -214,13 +219,17 @@ function InternalRoutes() {
const doesRouteMatch = useCallback(
(paths: string | string[]) => {
if (Array.isArray(paths)) {
const foundMatchingRoute = paths.find(
(path) =>
!!matchPath(config.basePath + path + '/*', location.pathname),
return paths.some((path) =>
matchPath(
{ path: config.basePath + path, end: false },
location.pathname,
),
);
return !!foundMatchingRoute;
} else {
return !!matchPath(config.basePath + paths + '/*', location.pathname);
return !!matchPath(
{ path: config.basePath + paths, end: false },
location.pathname,
);
}
},
[location.pathname],
Expand Down Expand Up @@ -270,7 +279,8 @@ function InternalRoutes() {
},
active:
doesRouteMatch('/buckets') ||
doesRouteMatch('/accounts/:accountName/buckets'),
doesRouteMatch('/accounts/:accountName/buckets') ||
doesRouteMatch('/accounts/:accountName/data/buckets'),
},
{
label: 'Workflows',
Expand All @@ -280,7 +290,8 @@ function InternalRoutes() {
},
active:
doesRouteMatch('/workflows') ||
doesRouteMatch('/accounts/:accountName/workflows'),
doesRouteMatch('/accounts/:accountName/workflows') ||
doesRouteMatch('/accounts/:accountName/data/workflows'),
},
...(isStorageManager
? [
Expand Down
22 changes: 20 additions & 2 deletions src/react/account/AccountRoleSelectButtonAndModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Icon, Stack, Tooltip, Wrap } from '@scality/core-ui';
import { Box, Button, Table } from '@scality/core-ui/dist/next';
import { useMemo, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import {
useCurrentAccount,
useDataServiceRole,
Expand Down Expand Up @@ -132,6 +133,8 @@ export function AccountRoleSelectButtonAndModal({
setIsModalOpen(false);
};

console.log({ accountName });

return (
<>
<AccountSelectorButton
Expand Down Expand Up @@ -189,7 +192,22 @@ const ModalFooter = ({
roleArn,
assumedAccount,
}) => {
const navigate = useBasenameRelativeNavigate();
const navigateWithBasename = useBasenameRelativeNavigate();
const navigate = useNavigate();
const { accountName } = useParams();
const location = useLocation();

const handleAccountClick = () => {
const replacePath = location.pathname.replace(accountName, assumedAccount);

if (replacePath.includes('/buckets')) {
navigateWithBasename(`/accounts/${assumedAccount}/data/buckets`);
} else if (replacePath.includes('/workflows')) {
navigateWithBasename(`/accounts/${assumedAccount}/data/workflows`);
} else {
navigate(replacePath);
}
};

return (
<Wrap>
Expand All @@ -201,7 +219,7 @@ const ModalFooter = ({
variant="primary"
onClick={() => {
setRole({ roleArn: assumedRoleArn });
navigate(`/accounts/${assumedAccount}/buckets`);
handleAccountClick();
handleClose();
}}
label="Continue"
Expand Down
6 changes: 4 additions & 2 deletions src/react/databrowser/buckets/Buckets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function Buckets() {
(state: AppState) =>
state.instanceStatus.latest.metrics?.['ingest-schedule']?.states,
);
const { bucketName: bucketNameParam } = useParams<{
const { bucketName: bucketNameParam, accountName } = useParams<{
bucketName: string;
accountName: string;
}>();
Expand Down Expand Up @@ -85,9 +85,11 @@ export default function Buckets() {
}

// Replace the old bucket name with the new one when switching accounts

if (
bucketNameParam &&
!buckets.value.some((bucket) => bucket.name === bucketNameParam)
!buckets.value.some((bucket) => bucket.name === bucketNameParam) &&
accountName === account?.Name
) {
return (
<Navigate
Expand Down
9 changes: 4 additions & 5 deletions src/react/databrowser/objects/MetadataSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useRef, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import styled from 'styled-components';

import { Icon, spacing } from '@scality/core-ui';
import { Input } from '@scality/core-ui/dist/next';
import { Hint, Hints, HintsTitle } from '../../ui-elements/Input';
import {
SearchButton,
Expand All @@ -14,9 +16,6 @@ import {
usePrefixWithSlash,
useQueryParams,
} from '../../utils/hooks';
import { Icon, spacing } from '@scality/core-ui';
import { Input } from '@scality/core-ui/dist/next';
import { useBasenameRelativeNavigate } from '../../ShellHooksContext';

export const METADATA_SEARCH_HINT_ITEMS = [
{
Expand Down Expand Up @@ -72,7 +71,7 @@ type Props = {

const MetadataSearch = ({ isMetadataType, errorZenkoMsg }: Props) => {
const [hintsShown, setHintsShown] = useState(false);
const navigate = useBasenameRelativeNavigate();
const navigate = useNavigate();
const query = useQueryParams();
const { pathname } = useLocation();
const prefixWithSlash = usePrefixWithSlash();
Expand Down
29 changes: 14 additions & 15 deletions src/react/databrowser/objects/ObjectList.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import * as T from '../../ui-elements/Table';
import { Icon, spacing, Toggle } from '@scality/core-ui';
import { Box } from '@scality/core-ui/dist/next';
import { List } from 'immutable';
import { useDispatch, useSelector } from 'react-redux';
import { useLocation, useNavigate } from 'react-router-dom';
import { ListObjectsType, ObjectEntity } from '../../../types/s3';
import { LIST_OBJECT_VERSIONS_S3_TYPE } from '../../utils/s3';
import { maybePluralize } from '../../utils';
import { AppState } from '../../../types/state';
import {
openFolderCreateModal,
openObjectDeleteModal,
openObjectUploadModal,
} from '../../actions';
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from '../../../types/state';
import { List } from 'immutable';
import MetadataSearch from './MetadataSearch';
import ObjectListTable from './ObjectListTable';
import { Icon, spacing, Toggle } from '@scality/core-ui';
import { WarningMetadata } from '../../ui-elements/Warning';
import { useQueryParams } from '../../utils/hooks';
import { useLocation } from 'react-router-dom';
import { Box } from '@scality/core-ui/dist/next';
import { useBucketVersionning } from '../../next-architecture/domain/business/buckets';
import * as T from '../../ui-elements/Table';
import { VEEAM_XML_PREFIX } from '../../ui-elements/Veeam/VeeamConstants';
import { useBasenameRelativeNavigate } from '../../ShellHooksContext';
import { WarningMetadata } from '../../ui-elements/Warning';
import { maybePluralize } from '../../utils';
import { useQueryParams } from '../../utils/hooks';
import { LIST_OBJECT_VERSIONS_S3_TYPE } from '../../utils/s3';
import MetadataSearch from './MetadataSearch';
import ObjectListTable from './ObjectListTable';
type Props = {
objects: List<ObjectEntity>;
bucketName: string;
Expand All @@ -35,7 +34,7 @@ export default function ObjectList({
toggled,
listType,
}: Props) {
const navigate = useBasenameRelativeNavigate();
const navigate = useNavigate();
const dispatch = useDispatch();
const { pathname } = useLocation();
const query = useQueryParams();
Expand Down
5 changes: 2 additions & 3 deletions src/react/databrowser/objects/ObjectRow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import isDeepEqual from 'lodash.isequal';
import memoize from 'memoize-one';
import { memo } from 'react';
import { useLocation } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import { areEqual } from 'react-window';
import { Dispatch } from 'redux';

Expand All @@ -10,7 +10,6 @@ import { ObjectEntity } from '../../../types/s3';
import { toggleAllObjects } from '../../actions';
import * as T from '../../ui-elements/Table';
import { useQueryParams } from '../../utils/hooks';
import { useBasenameRelativeNavigate } from '../../ShellHooksContext';

type PrepareRow = (arg0: RowType) => void;
type RowType = {
Expand Down Expand Up @@ -50,7 +49,7 @@ const Row = ({
}: RowProps) => {
const row = rows[index];
prepareRow(row);
const navigate = useBasenameRelativeNavigate();
const navigate = useNavigate();
const { pathname } = useLocation();
const query = useQueryParams();
const versionId = query.get('versionId');
Expand Down
4 changes: 2 additions & 2 deletions src/react/databrowser/objects/Objects.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
import { Redirect, useParams } from 'react-router-dom';
import { Navigate, useParams } from 'react-router-dom';
import {
getObjectMetadata,
listObjects,
Expand Down Expand Up @@ -117,7 +117,7 @@ export default function Objects() {
}

if (!bucketNameParam) {
return <Redirect to={'/buckets'} />;
return <Navigate to={'/buckets'} replace />;
}

// TODO: manage empty state
Expand Down
15 changes: 12 additions & 3 deletions src/react/ui-elements/Breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import styled from 'styled-components';
import AccountRoleSelectButtonAndModal from '../account/AccountRoleSelectButtonAndModal';
import { fontSize } from '@scality/core-ui/dist/style/theme';
import { useConfig } from '../next-architecture/ui/ConfigProvider';

// vendor from `polished` package
type Styles = {
Expand Down Expand Up @@ -224,8 +225,10 @@ export function Breadcrumb({ breadcrumbPaths }: Props) {
}

export function BreadcrumbAccount({ pathname }: { pathname: string }) {
const config = useConfig();

const matchAccountUserAccessKey = matchPath(
'/accounts/:accountName/users/:userName/access-keys',
config.basePath + '/accounts/:accountName/users/:userName/access-keys',
pathname,
);

Expand All @@ -241,7 +244,10 @@ export function BreadcrumbAccount({ pathname }: { pathname: string }) {
);
}

const matchAccountRoute = matchPath('/accounts/:accountName', pathname);
const matchAccountRoute = matchPath(
config.basePath + '/accounts/:accountName' + '/*',
pathname,
);

if (matchAccountRoute) {
return (
Expand All @@ -251,7 +257,10 @@ export function BreadcrumbAccount({ pathname }: { pathname: string }) {
);
}

const matchAllAccountsRoute = matchPath('/accounts/', pathname);
const matchAllAccountsRoute = matchPath(
config.basePath + '/accounts/',
pathname,
);

if (matchAllAccountsRoute) {
return (
Expand Down
15 changes: 3 additions & 12 deletions src/react/ui-elements/PrivateRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Redirect, Route } from 'react-router-dom';
import { Navigate, Route } from 'react-router-dom';
import React from 'react';
import { connect } from 'react-redux';

Expand All @@ -8,16 +8,7 @@ function PrivateRoute(props) {
if (props.authenticated) {
return <Route {...rest} component={component} />;
} else {
return (
<Redirect
to={{
pathname: '/login',
state: {
path: props.pathname,
},
}}
/>
);
return <Navigate to="/login" />;
}
}

Expand All @@ -28,4 +19,4 @@ function mapStateToProps(state) {
};
}

export default connect(mapStateToProps)(PrivateRoute);
export default connect(mapStateToProps)(PrivateRoute);
Loading

0 comments on commit e8a0b49

Please sign in to comment.