Skip to content

Commit

Permalink
ARTESCA-13970 // Migration to React 18
Browse files Browse the repository at this point in the history
Add TypeScript declaration files and update .gitignore

Add react-test-renderer dependency to package.json and package-lock.json

Update react-router to v6 and refactor navigation hooks in components

Refactor Tabs component to improve path handling and integrate Outlet for nested routes

Refactor MetricTimespanProvider to accept location prop for improved URL handling

Refactor MetricTimespanProvider to use useLocation for improved location handling

Add dist/ to .gitignore to exclude distribution files from version control

Remove unused configuration and mock files to clean up the repository

Add configuration files and setup for project environment
  • Loading branch information
hervedombya committed Dec 12, 2024
1 parent a471292 commit c2c0b22
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 242 deletions.
306 changes: 152 additions & 154 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
"@storybook/storybook-deployer": "^2.8.16",
"@storybook/theming": "^8.3.6",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/react": "^15.0.7",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.0",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
"@types/react-table": "^7.7.11",
Expand Down Expand Up @@ -109,16 +109,17 @@
"framer-motion": "^4.1.17",
"polished": "3.4.1",
"pretty-bytes": "^5.6.0",
"react": "^17.0.2",
"react": "^18.3.1",
"react-debounce-input": "3.2.2",
"react-dom": "^17.0.2",
"react-dom": "^18.3.1",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.49.2",
"react-query": "^3.34.0",
"react-router": "5.2.0",
"react-router-dom": "5.2.0",
"react-router": "^6.28.0",
"react-router-dom": "^6.28.0",
"react-select": "4.3.1",
"react-table": "^7.7.0",
"react-test-renderer": "^18.3.1",
"react-virtualized": "9.22.3",
"react-virtualized-auto-sizer": "^1.0.24",
"react-window": "^1.8.6",
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/emptystate/Emptystate.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button } from '../buttonv2/Buttonv2.component';
import { Icon, IconName } from '../icon/Icon.component';
import { LargeText } from '../text/Text.component';
import { CoreUITheme } from '../../style/theme';
import { useHistory } from 'react-router';
import { useNavigate } from 'react-router';

export type Props = {
listedResource: {
Expand Down Expand Up @@ -48,7 +48,7 @@ export const ActionWrapper = styled.div`
function EmptyState(props: Props) {
const { icon, listedResource, link, resourceToCreate, backgroundColor } =
props;
const history = useHistory();
const navigate = useNavigate();
return (
<EmptystateContainer
className="sc-emptystate"
Expand All @@ -74,7 +74,7 @@ function EmptyState(props: Props) {
icon={<Icon name="Create-add" />}
type="button"
variant="primary"
onClick={() => history.push(link)}
onClick={() => navigate(link)}
/>
</ActionWrapper>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/inputlist/InputList.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Input } from '../inputv2/inputv2';
import { AddButton, SubButton } from './InputButtons';

export type InputListProps<T> = Omit<HTMLProps<HTMLInputElement>, 'size'> & {
ref: RefCallBack;
ref?: RefCallBack;
min?: string | number;
max?: string | number;
maxLength?: number;
Expand Down
10 changes: 5 additions & 5 deletions src/lib/components/linetemporalchart/MetricTimespanProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React from 'react';
import { useEffect, useState, createContext, useContext } from 'react';
import { createContext, useContext, useEffect, useState } from 'react';
import { QueryTimeSpan, queryTimeSpansCodes } from '../constants';
import { useLocation } from 'react-router-dom';
import { QueryTimeSpan } from '../constants';
import { queryTimeSpansCodes } from '../constants';
export const MetricsTimeSpanContext = createContext<QueryTimeSpan | null>(null);
export const MetricsTimeSpanProvider = ({
children,
location,
}: {
children: JSX.Element;
location?: ReturnType<typeof useLocation>;
}) => {
// the default timespan is the last 24h
const [queryTimeSpanCode, setQueryTimeSpanCode] = useState(
queryTimeSpansCodes[1],
);
const urlSearchParams = new URLSearchParams(useLocation().search);
const urlSearchParams = new URLSearchParams(location?.search);
const queryTimeSpan = urlSearchParams.get('from');
// Sync url timespan to local timespan
useEffect(() => {
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/tablev2/SearchWithQueryParams.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import { TableSearch as Search, SearchProps } from './Search';

export type SearchWithQueryParamsProps = {
Expand All @@ -10,15 +10,15 @@ export type SearchWithQueryParamsProps = {
export function SearchWithQueryParams(props: SearchWithQueryParamsProps) {
const { queryParams = 'search', onChange, ...rest } = props;
const { search, pathname } = useLocation();
const history = useHistory();
const navigate = useNavigate();
const params = new URLSearchParams(search);
const initialValue = params.get(queryParams) || '';
const [value, setValue] = useState(initialValue);

function handleOnChange(value: string) {
const { onChange } = props;
params.set(queryParams, value);
history.replace(`${pathname}?${params.toString()}`);
navigate(`${pathname}?${params.toString()}`, { replace: true });
setValue(value);

if (typeof onChange === 'function') {
Expand Down
4 changes: 3 additions & 1 deletion src/lib/components/tablev2/TableCommon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ type VirtualizedRowsType<
DATA_ROW extends Record<string, unknown> = Record<string, unknown>,
> = {
rows: Row<DATA_ROW>[];
RenderRow: ComponentType<ListChildComponentProps<Row<DATA_ROW>[]>>;
RenderRow: ComponentType<
React.PropsWithChildren<ListChildComponentProps<Row<DATA_ROW>[]>>
>;
rowHeight: TableHeightKeyType;
setHasScrollbar: React.Dispatch<React.SetStateAction<boolean>>;
hasScrollbar?: boolean;
Expand Down
116 changes: 57 additions & 59 deletions src/lib/components/tabsv2/Tabsv2.component.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
import React, {
createContext,
ReactElement,
useCallback,
useEffect,
useState,
useCallback,
ReactElement,
} from 'react';
import {
TabBar,
Outlet,
Route,
Routes,
useLocation,
useNavigate,
} from 'react-router-dom';
import styled from 'styled-components';
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
import { BasicText, EmphaseText, SecondaryText } from '../text/Text.component';
import { ScrollButton } from './ScrollButton';
import {
ScrollableContainer,
TabBar,
TabContent,
TabItem,
TabsContainer,
TabsScroller,
} from './StyledTabs';
import {
useHistory,
useLocation,
useRouteMatch,
matchPath,
Route,
Switch,
} from 'react-router-dom';
import { SecondaryText, BasicText, EmphaseText } from '../text/Text.component';
import { ScrollButton } from './ScrollButton';
import { Tab } from './Tab';
import { TabProps, Query } from './Tab';
import { Query, Tab, TabProps } from './Tab';
import { useScrollingTabs } from './useScrollingTabs';
import { ButtonIcon } from '../buttonv2/Buttonv2.component';
import styled from 'styled-components';

type TabsProps = {
activeTabColor?: string;
Expand Down Expand Up @@ -59,8 +57,8 @@ function Tabs({
...rest
}: TabsProps) {
const location = useLocation();
const history = useHistory();
const { url } = useRouteMatch();
const navigate = useNavigate();
const url = location.pathname;
const [selectedTabIndex, setSelectedTabIndex] = useState<
number | null | undefined
>(null);
Expand Down Expand Up @@ -101,24 +99,26 @@ function Tabs({
};

const getPushHistoryPath = (path: string, query?: Query): string => {
const sanitizedSegment = path.replace(/^\/+/, '');
const replaceUrl = location.pathname.replace(/[^/]+$/, sanitizedSegment);

if (path.startsWith('/')) {
return `${path}${serialize(query)}`;
return `${replaceUrl}${serialize(query)}`;
}
return `${url}/${path}${serialize(query)}`;

return `${replaceUrl}/${path}${serialize(query)}`;
};

useEffect(() => {
let hasSelectedTab = false;
filteredTabsChildren.forEach((child, index) => {
const fullPath = child.props.path.startsWith('/')
? child.props.path
: url + '/' + child.props.path;

const isSelected =
!!matchPath(location.pathname, {
path: child.props.path.startsWith('/')
? child.props.path
: url + '/' + child.props.path,
exact: child.props.exact,
strict: child.props.strict,
sensitive: child.props.sensitive,
}) && (child.props.query ? matchQuery(child.props.query) : true);
location.pathname.match(new RegExp(`^${fullPath}$`, 'i')) &&
(child.props.query ? matchQuery(child.props.query) : true);

if (isSelected) {
setSelectedTabIndex(index);
Expand All @@ -127,6 +127,7 @@ function Tabs({
});
if (!hasSelectedTab) setSelectedTabIndex(null);
}, [location.pathname, filteredTabsChildren, matchQuery]);

const {
scrollButtonEndRef,
scrollButtonStartRef,
Expand All @@ -149,12 +150,13 @@ function Tabs({
...childRest
}: TabProps = child.props;
const isSelected = selectedTabIndex === index;
const realPath = `/${path.split('/').pop()}`;
return (
<TabItem
className={`sc-tabs-item ${isSelected ? 'selected' : ''}`}
key={index}
role="tab"
onClick={() => history.push(getPushHistoryPath(path, query))}
onClick={() => navigate(getPushHistoryPath(realPath, query))}
selected={isSelected}
tabHoverColor={tabHoverColor}
inactiveTabColor={inactiveTabColor}
Expand All @@ -168,7 +170,7 @@ function Tabs({
event.key === 'Spacebar'
) {
event.preventDefault();
history.push(getPushHistoryPath(path, query));
navigate(getPushHistoryPath(realPath, query));
}
}}
{...childRest}
Expand Down Expand Up @@ -218,38 +220,34 @@ function Tabs({
/>
)}
</ScrollableContainer>

{filteredTabsChildren.map((tab, index) => (
<Route
exact={tab.props.exact}
sensitive={tab.props.sensitive}
strict={tab.props.strict}
path={
tab.props.path.startsWith('/')
? tab.props.path
: url + '/' + tab.props.path
}
key={index}
>
{!tab.props.query ||
(tab.props.query && matchQuery(tab.props.query)) ? (
<TabContent
className="sc-tabs-item-content"
tabContentColor={tabContentColor}
withoutPadding={tab.props.withoutPadding}
>
{tab.props.children}
</TabContent>
) : (
<></>
)}
</Route>
))}
<Routes>
{filteredTabsChildren.map((tab, index) => {
const path = tab.props.path.split('/').pop();
return (
<Route
key={index}
path={`/${path}`}
element={
<>
<TabContent
className="sc-tabs-item-content"
tabContentColor={tabContentColor}
withoutPadding={tab.props.withoutPadding}
>
{tab.props.children}
</TabContent>
<Outlet />
</>
}
/>
);
})}
</Routes>
</TabsContainer>
</TabsContext.Provider>
);
}

Tabs.Tab = Tab;
// re-export Tab
export { Tabs, Tab };
export { Tab, Tabs };
2 changes: 1 addition & 1 deletion src/lib/components/toast/ToastProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const ToastContext = createContext<ToastContextType | undefined>(
interface ToastProviderProps {
children: ReactNode;
}
export const ToastProvider: React.FC<ToastProviderProps> = ({ children }) => {
export const ToastProvider: React.FC<React.PropsWithChildren<ToastProviderProps>> = ({ children }) => {
const [toastProps, setToastProps] = useState<ToastContextState | null>(null);

const showToast = (toastProps: ToastContextState) => {
Expand Down
18 changes: 10 additions & 8 deletions src/lib/organisms/attachments/AttachmentConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ComponentType, useState } from 'react';
import { Column, Table } from '../../components/tablev2/Tablev2.component';
import { Box, Button } from '../../next';
import { useMutation, UseMutationOptions } from 'react-query';
import { AttachmentOperation, AttachmentAction } from './AttachmentTypes';
import { useNavigate } from 'react-router';
import { useTheme } from 'styled-components';
import { useHistory } from 'react-router';
import { Icon, LargerText, Modal, SecondaryText, Stack, Wrap } from '../..';
import { Column, Table } from '../../components/tablev2/Tablev2.component';
import { Box, Button } from '../../next';
import { AttachmentAction, AttachmentOperation } from './AttachmentTypes';

type AttachmentStatus = 'Waiting for confirmation' | 'Error' | 'Success';

Expand Down Expand Up @@ -40,15 +40,17 @@ export function AttachmentConfirmationModal<
resourceName: string;
resourceType: RESOURCE_TYPE;
redirectUrl: string;
EntityIcon: ComponentType<{ type: ENTITY_TYPE | RESOURCE_TYPE }>;
EntityIcon: ComponentType<
React.PropsWithChildren<{ type: ENTITY_TYPE | RESOURCE_TYPE }>
>;
cancelButtonDisabled?: boolean;
onCancel?: () => void;
onExit?: (
successfullOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[],
failedOperations: AttachmentOperation<ENTITY_TYPE, ENTITY>[],
) => void;
}) {
const history = useHistory();
const navigate = useNavigate();

const [isModalOpen, setIsModalOpen] = useState(false);

Expand Down Expand Up @@ -133,7 +135,7 @@ export function AttachmentConfirmationModal<
onExit(successfulOperations, failedOperations);
}
handleClose();
history.push(redirectUrl);
navigate(redirectUrl);
};
const modalFooter = () => {
return (
Expand Down Expand Up @@ -282,7 +284,7 @@ export function AttachmentConfirmationModal<
disabled={cancelButtonDisabled}
onClick={() => {
if (onCancel) onCancel();
history.push(redirectUrl);
navigate(redirectUrl);
}}
/>
<Button
Expand Down

0 comments on commit c2c0b22

Please sign in to comment.