Skip to content

Commit

Permalink
feat: Add Insights wrapper hooks and components for router v6
Browse files Browse the repository at this point in the history
  • Loading branch information
bastilian committed Jun 12, 2023
1 parent 943f58f commit cfbc0bf
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 7 deletions.
22 changes: 22 additions & 0 deletions packages/components/src/InsightsLink/InsightsLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import { Link, LinkProps } from 'react-router-dom';
import useChrome from '../useChrome';
import { buildInsightsPath } from '@redhat-cloud-services/frontend-components-utilities/helpers/urlPathHelpers';

interface InsightsLinkProps {
to: LinkProps['to'];
app: string;
}

const InsightsLink: React.FC<InsightsLinkProps> = ({ to, app, ...props }) => {
const chrome = useChrome();
const toPath = buildInsightsPath(chrome, app, to);

return (
<Link to={toPath} {...props}>
{props.children}
</Link>
);
};

export default InsightsLink;
2 changes: 2 additions & 0 deletions packages/components/src/InsightsLink/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './InsightsLink';
export { default as InsightsLink } from './InsightsLink';
7 changes: 6 additions & 1 deletion packages/components/src/Inventory/AppInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStore } from 'react-redux';
import { Bullseye, Spinner } from '@patternfly/react-core';
import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import WithHistory from './WithHistory';

const BaseAppInfo = (props) => {
const store = useStore();
Expand All @@ -13,6 +14,7 @@ const BaseAppInfo = (props) => {
<Cmp className={classNames(props.className, 'inventory')}>
<Suspense fallback={props.fallback}>
<ScalprumComponent
history={props.history}
store={store}
appName="inventory"
module="./AppInfo"
Expand All @@ -31,6 +33,7 @@ BaseAppInfo.propTypes = {
innerRef: PropTypes.object,
component: PropTypes.string,
className: PropTypes.string,
history: PropTypes.object,
};

/**
Expand Down Expand Up @@ -58,4 +61,6 @@ AppInfo.defaultProps = {
component: 'section',
};

export default AppInfo;
const CompatiblityWrapper = (props, ref) => <WithHistory innerRef={ref} Component={AppInfo} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
7 changes: 6 additions & 1 deletion packages/components/src/Inventory/DetailWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStore } from 'react-redux';
import { Bullseye, Spinner } from '@patternfly/react-core';
import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import WithHistory from './WithHistory';

const BaseDetailWrapper = (props) => {
const store = useStore();
Expand All @@ -13,6 +14,7 @@ const BaseDetailWrapper = (props) => {
<Cmp className={classNames(props.className, 'inventory')}>
<Suspense fallback={props.fallback}>
<ScalprumComponent
history={props.history}
store={store}
appName="inventory"
module="./DetailWrapper"
Expand All @@ -31,6 +33,7 @@ BaseDetailWrapper.propTypes = {
innerRef: PropTypes.object,
component: PropTypes.string,
className: PropTypes.string,
history: PropTypes.object,
};

/**
Expand Down Expand Up @@ -58,4 +61,6 @@ DetailWrapper.defaultProps = {
component: 'section',
};

export default DetailWrapper;
const CompatiblityWrapper = (props, ref) => <WithHistory innerRef={ref} Component={DetailWrapper} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
7 changes: 6 additions & 1 deletion packages/components/src/Inventory/InventoryDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStore } from 'react-redux';
import { Bullseye, Spinner } from '@patternfly/react-core';
import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import WithHistory from './WithHistory';

const BaseInventoryDetail = (props) => {
const store = useStore();
Expand All @@ -13,6 +14,7 @@ const BaseInventoryDetail = (props) => {
<Cmp className={classNames(props.className, 'inventory')}>
<Suspense fallback={props.fallback}>
<ScalprumComponent
history={props.history}
store={store}
appName="inventory"
module="./InventoryDetail"
Expand All @@ -31,6 +33,7 @@ BaseInventoryDetail.propTypes = {
innerRef: PropTypes.object,
component: PropTypes.string,
className: PropTypes.string,
history: PropTypes.object,
};

/**
Expand Down Expand Up @@ -58,4 +61,6 @@ InventoryDetail.defaultProps = {
component: 'section',
};

export default InventoryDetail;
const CompatiblityWrapper = (props, ref) => <WithHistory innerRef={ref} Component={InventoryDetail} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
7 changes: 6 additions & 1 deletion packages/components/src/Inventory/InventoryDetailHead.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStore } from 'react-redux';
import { Bullseye, Spinner } from '@patternfly/react-core';
import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import WithHistory from './WithHistory';

const BaseInventoryDetailHead = (props) => {
const store = useStore();
Expand All @@ -13,6 +14,7 @@ const BaseInventoryDetailHead = (props) => {
<Cmp className={classNames(props.className, 'inventory')}>
<Suspense fallback={props.fallback}>
<ScalprumComponent
history={props.history}
store={store}
appName="inventory"
module="./InventoryDetailHead"
Expand All @@ -31,6 +33,7 @@ BaseInventoryDetailHead.propTypes = {
innerRef: PropTypes.object,
component: PropTypes.string,
className: PropTypes.string,
history: PropTypes.object,
};

/**
Expand Down Expand Up @@ -58,4 +61,6 @@ InventoryDetailHead.defaultProps = {
component: 'section',
};

export default InventoryDetailHead;
const CompatiblityWrapper = (props, ref) => <WithHistory innerRef={ref} Component={InventoryDetailHead} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
7 changes: 6 additions & 1 deletion packages/components/src/Inventory/InventoryTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useStore } from 'react-redux';
import { Bullseye, Spinner } from '@patternfly/react-core';
import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import WithHistory from './WithHistory';

const BaseInvTable = (props) => {
const store = useStore();
Expand All @@ -13,6 +14,7 @@ const BaseInvTable = (props) => {
<Cmp className={classNames(props.className, 'inventory')}>
<Suspense fallback={props.fallback}>
<ScalprumComponent
history={props.history}
store={store}
appName="inventory"
module="./InventoryTable"
Expand All @@ -31,6 +33,7 @@ BaseInvTable.propTypes = {
innerRef: PropTypes.object,
component: PropTypes.string,
className: PropTypes.string,
history: PropTypes.object,
};

/**
Expand Down Expand Up @@ -58,4 +61,6 @@ InvTable.defaultProps = {
component: 'section',
};

export default InvTable;
const CompatiblityWrapper = (props, ref) => <WithHistory innerRef={ref} Component={InvTable} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
6 changes: 5 additions & 1 deletion packages/components/src/Inventory/TagWithDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import InventoryLoadError from './InventoryLoadError';
import classNames from 'classnames';
import { AsyncComponentProps, ExcludeModulesKeys } from '../AsyncComponent';
import { ChromeAPI } from '@redhat-cloud-services/types';
import WithHistory from './WithHistory';

export type TagWithDialogProps = Omit<AsyncComponentProps, ExcludeModulesKeys>;

Expand All @@ -18,6 +19,7 @@ const BaseTagWithDialog: React.FC<TagWithDialogProps> = (props) => {
const store = useStore();
const Cmp = props.component;
const SCProps: ScalprumComponentProps<ChromeAPI, TagWithDialogProps> = {
history: props.history,
store,
appName: 'inventory',
module: './TagWithDialog',
Expand Down Expand Up @@ -55,4 +57,6 @@ const TagWithDialog: React.FC<TagWithDialogProps> = React.forwardRef(
) => <BaseTagWithDialog innerRef={ref} component={component} fallback={fallback} {...props} />
);

export default TagWithDialog;
const CompatiblityWrapper = (props: any, ref: any) => <WithHistory innerRef={ref} Component={TagWithDialog} {...props} />;

export default React.forwardRef(CompatiblityWrapper);
27 changes: 27 additions & 0 deletions packages/components/src/Inventory/WithHistory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// @ts-nocheck
import React, { useMemo } from 'react';
import * as reactRouter from 'react-router-dom';
import useChrome from '../useChrome';

const WithReactRouterHistory = ({ Component, ...props }) => {
const history = reactRouter.useHistory();

return <Component history={history} {...props} />;
};

const WithChromeHistory = ({ Component, ...props }) => {
const { chromeHistory } = useChrome();

return <Component history={chromeHistory} {...props} />;
};

const WithHistory = ({ Component, ...props }, ref) => {
const HistoryComponent = useMemo(
() => (typeof reactRouter.useHistory === 'function' ? WithReactRouterHistory : WithChromeHistory),
[Component, props]
);

return <HistoryComponent innerRef={ref} Component={Component} {...props} />;
};

export default React.forwardRef(WithHistory);
1 change: 0 additions & 1 deletion packages/components/src/useChrome/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './useChrome';
export { default } from './useChrome';
export { default as useChrome } from './useChrome';
1 change: 1 addition & 0 deletions packages/utils/src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * as default from './helpers';
export * from './helpers';
export * from './urlPathHelpers';
18 changes: 18 additions & 0 deletions packages/utils/src/helpers/urlPathHelpers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { buildInsightsPath } from './urlPathHelpers';

const fakeChrome = {
isBeta: jest.fn(() => false),
getBundle: jest.fn(() => 'insights'),
getApp: jest.fn(() => 'compliance'),
};

describe('buildInsightsPath', () => {
it('should return a path', () => {
expect(buildInsightsPath(fakeChrome, 'compliance', '/scappolicies')).toEqual('/insights/compliance/scappolicies');
});

it('should return a preview path when isBeta is true', () => {
fakeChrome.isBeta.mockImplementation(() => true);
expect(buildInsightsPath(fakeChrome, 'compliance', '/scappolicies')).toEqual('/preview/insights/compliance/scappolicies');
});
});
17 changes: 17 additions & 0 deletions packages/utils/src/helpers/urlPathHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable import/prefer-default-export */
import { ChromeAPI } from '@redhat-cloud-services/types';

export const buildInsightsPath = (chrome: ChromeAPI, app: string, toProp: any) => {
const inAppPath = (typeof toProp === 'object' ? toProp.pathname : toProp) || '';
const isAbsolutePath = /^\//.test(inAppPath);
const environmentPath = chrome.isBeta() ? '/preview' : '';
const appPath = app || chrome.getApp();
const pathname = isAbsolutePath ? [environmentPath, chrome.getBundle(), appPath, inAppPath.replace(/^\//, '')].join('/') : inAppPath;

return typeof toProp === 'object'
? {
...toProp,
pathname,
}
: pathname;
};
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export { default as routerParams } from './RouterParams';
export { default as RowLoader } from './RowLoader';
export { useInventory } from './useInventory';
export * from './CypressUtils';
export * from './useInsightsNavigate';
2 changes: 2 additions & 0 deletions packages/utils/src/useInsightsNavigate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './useInsightsNavigate';
export * from './useInsightsNavigate';
14 changes: 14 additions & 0 deletions packages/utils/src/useInsightsNavigate/useInsightsNavigate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// @ts-ignore
import { useNavigate } from 'react-router-dom';
// @ts-ignore
import useChrome from '@redhat-cloud-services/frontend-components/useChrome';
import { buildInsightsPath } from '../helpers/urlPathHelpers';

const useInsightsNavigate = (app: string) => {
const navigate = useNavigate();
const chrome = useChrome();

return (to: any) => navigate(buildInsightsPath(chrome, app, to));
};

export default useInsightsNavigate;

0 comments on commit cfbc0bf

Please sign in to comment.