Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resource tab optimization #1435

Merged
merged 35 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
360e920
saving temp changes
arivepr Sep 23, 2021
b060909
Merge branch 'master' into ResourceTabOptimization
arivepr Sep 23, 2021
f66ace8
Merge branch 'master' into ResourceTabOptimization
arivepr Oct 3, 2021
0f725de
testing bits
arivepr Oct 4, 2021
41b0aa2
Merge branch 'master' into ResourceTabOptimization
arivepr Oct 5, 2021
c16159d
further testing
arivepr Oct 6, 2021
d6a7d8e
Merge branch 'master' into ResourceTabOptimization
arivepr Oct 6, 2021
862b09e
more tests
arivepr Oct 6, 2021
9f9fa98
Merge branch 'master' into ResourceTabOptimization
arivepr Oct 21, 2021
990535d
adding api call
arivepr Oct 28, 2021
ffc7b1f
Adding new validation for resource tab
arivepr Nov 1, 2021
0c28d0d
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 1, 2021
cb55806
code change
arivepr Nov 2, 2021
7e5812f
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 2, 2021
56c9b9b
adding reducer mutators for ros visibility
arivepr Nov 4, 2021
ee2e804
adding reducer mutators for ros visibility
arivepr Nov 4, 2021
4a47bd5
touch up
arivepr Nov 4, 2021
c1dc3ec
Merge branch 'ResourceTabOptimization' of github.com:RedHatInsights/i…
arivepr Nov 4, 2021
704fdde
General code cleanup and linting
arivepr Nov 4, 2021
17edc4d
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 4, 2021
3575e61
re adding rendering condition to resource tab
arivepr Nov 4, 2021
8269f05
saving changes
arivepr Nov 17, 2021
9c3a67f
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 17, 2021
a1edabf
Adding reducer and component changes
arivepr Nov 17, 2021
e4a4a8a
Testing new logic
arivepr Nov 17, 2021
5588d18
adding conditional statement for tabs filtering
arivepr Nov 17, 2021
8445da6
Fixed logic, working as needed now.
arivepr Nov 17, 2021
4d12d28
Cleaning up code
arivepr Nov 17, 2021
f8d09f8
Adding adjustment for test
arivepr Nov 17, 2021
b33a445
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 19, 2021
f972f94
Merge branch 'master' into ResourceTabOptimization
arivepr Nov 23, 2021
4eb549f
Addressing changes for code optimization
arivepr Nov 23, 2021
b2f87ed
Merge branch 'ResourceTabOptimization' of github.com:RedHatInsights/i…
arivepr Nov 23, 2021
327f6e3
Fixed failing tests
arivepr Nov 23, 2021
80a28e0
Adding wrapping for code
arivepr Nov 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/components/InventoryDetail/ApplicationDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ApplicationDetails = ({ onTabSelect, appList, ...props }) => {
const history = useHistory();
const dispatch = useDispatch();
const searchParams = new URLSearchParams(search);
const items = useSelector(({ entityDetails }) => entityDetails?.activeApps);
const items = useSelector(({ entityDetails }) => entityDetails?.activeApps.filter(({ isVisible }) => isVisible !== false));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add another guard in here

Suggested change
const items = useSelector(({ entityDetails }) => entityDetails?.activeApps.filter(({ isVisible }) => isVisible !== false));
const items = useSelector(({ entityDetails }) => (entityDetails?.activeApps || []).filter(({ isVisible }) => isVisible !== false));

const activeApp = useSelector(({ entityDetails }) => entityDetails?.activeApp);
const defaultApp = activeApp?.appName || appList?.find(({ pageId, name }) => items?.[0]?.name === (
pageId || name))?.name || items?.[0]?.name;
Expand Down
14 changes: 12 additions & 2 deletions src/components/InventoryDetail/InventoryDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import React, { useEffect, Fragment } from 'react';
import { useParams } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { loadEntity, deleteEntity } from '../../store/actions';
import { loadEntity, deleteEntity, setRosTabVisibility } from '../../store/actions';
import './InventoryDetail.scss';
import SystemNotFound from './SystemNotFound';
import TopBar from './TopBar';
import FactsInfo from './FactsInfo';
import { reloadWrapper } from '../../Utilities/index';
import { addNotification } from '@redhat-cloud-services/frontend-components-notifications/redux';
import ApplicationDetails from './ApplicationDetails';
import { getEntitySystemProfile } from '../../api/api';
import './InventoryDetail.scss';

/**
Expand Down Expand Up @@ -41,7 +42,16 @@ const InventoryDetail = ({
useEffect(() => {
const currId = inventoryId || location.pathname.replace(/\/$/, '').split('/').pop();
if (!entity || !(entity?.id === currId) || !loaded) {
dispatch(loadEntity(currId, { hasItems: true }, { showTags }));
const action = loadEntity(currId, { hasItems: true }, { showTags });
dispatch(action);
action.payload.then(() => {
getEntitySystemProfile(currId).then(result => {
const cloudProviderObj = (typeof result.results[0].system_profile.cloud_provider !== 'undefined')
&& result.results[0].system_profile.cloud_provider;
dispatch(setRosTabVisibility((cloudProviderObj === 'aws' || cloudProviderObj === 'azure')));
return result;
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd change the flow of action completely, instead of fetching the data and dispatching specific action for ROS, I'd disable the ROS tab by default. And I'd add new reducer that reacts to ACTION_TYPES.LOAD_SYSTEM_PROFILE and enables the ROS tab. resourceOptTabVisibility should be enough. This way we won't add additional logic to the shared InventoryDetail and at the same time make all custom tab hiding just for inventory app.

Approach in this PR (waiting for getEntitySystemProfile) could mean that ROS tab would not be visible even in ROS application itself, which is unwanted.

Copy link
Contributor

@Hyperkid123 Hyperkid123 Nov 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd disable the ROS tab by default.

@karelhala Yes by default the tab is disabled even now.

And I'd add a new reducer that reacts to ACTION_TYPES.LOAD_SYSTEM_PROFILE and enables the ROS tab.

Using the action type ACTION_TYPES.LOAD_SYSTEM_PROFILE can result in more race conditions when switching between detail pages 😞. Ideally, we would use the thunk middleware to chain the actions directly through redux though. Optimal way would be if the data was provided in the entity detail but that is not happening.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ROS tab should be disabled only on full inventory view. We can wait for the ACTION_TYPES.LOAD_SYSTEM_PROFILE (no need to fire a new one as it should already be fired) to load and enable the ROS tab in inventory app redux store and enable the tab if criterium is met. The problem I have with the approach in this PR is that we're adding extra logic to shared component just to disable the tab in inventory app.

Copy link
Contributor

@Hyperkid123 Hyperkid123 Nov 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, shouldn't this be handled by the ROS tab itself then?

To elaborate. Add an API that allows apps to control the visibility and let them decide to show/hide the content? We would not have to check the content at all. Plus now it's kind of strange. Suddenly, out of nowhere a new tab will appear.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's partially handleded by the ROS tab, they currently show empty state. But they don't want to show the tab at all for some users (I was against it, but the PM specifically required it)

Copy link
Contributor

@Hyperkid123 Hyperkid123 Nov 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I would personally move the responsibility to the team. As I said, provide a component API to specifically state which tabs to show. They will have full control and we have one thing less to worry about. I assume we will get requests for other tabs with similar behavior in the future. I think it may come in handy when you navigate through the URL. This can cause some strange behavior when you navigate directly through the URL, and your tab is missing for some reason and pops up later.

EDIT: Furthermore, if they have the empty state logic, they must be calling the APIs as well so we are basically doing the same thing twice for no real reason. Adding the tab visibility as a configuration is even more compelling at this point.

}
}, []);
return <div className="ins-entity-detail">
Expand Down
2 changes: 0 additions & 2 deletions src/components/InventoryTable/InventoryTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ const InventoryTable = forwardRef(({ // eslint-disable-line react/display-name
const onRefreshData = (options = {}, disableOnRefresh) => {
const { activeFilters } = store.getState().entities;
const cachedProps = cache.current?.getProps() || {};

// eslint-disable-next-line camelcase
const currPerPage = options?.per_page || options?.perPage || cachedProps.perPage;

const params = {
Expand Down
1 change: 1 addition & 0 deletions src/store/action-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ export const CLEAR_FILTERS = 'CLEAR_FILTERS';
export const TOGGLE_TAG_MODAL = 'TOGGLE_TAG_MODAL';
export const CONFIG_CHANGED = 'CONFIG_CHANGED';
export const TOGGLE_DRAWER = 'TOGGLE_INVENTORY_DRAWER';
export const SET_ROS_TAB_VISBILITY = 'SET_ROS_TAB_VISBILITY';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this const

8 changes: 7 additions & 1 deletion src/store/inventory-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
CLEAR_FILTERS,
TOGGLE_TAG_MODAL,
CONFIG_CHANGED,
TOGGLE_DRAWER
TOGGLE_DRAWER,
SET_ROS_TAB_VISBILITY
} from './action-types';
import {
getEntities as defaultGetEntities,
Expand Down Expand Up @@ -193,6 +194,11 @@ export const deleteEntity = (systems, displayName) => ({
}
});

export const setRosTabVisibility = (shouldShowRosTab) => ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this action, it should be enough to wait for the ACTION_TYPES.LOAD_SYSTEM_PROFILE. If such action is not fired when user is on ROS tab by default, we should fire the systemProfile action directly when InventoryDetail route is rendered.

type: SET_ROS_TAB_VISBILITY,
payload: shouldShowRosTab
});

export const configChanged = (config) => ({
type: CONFIG_CHANGED,
payload: config
Expand Down
30 changes: 23 additions & 7 deletions src/store/reducers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { INVENTORY_ACTION_TYPES, ACTION_TYPES, SELECT_ENTITY, SET_INVENTORY_FILTER, SET_PAGINATION } from './action-types';
import {
INVENTORY_ACTION_TYPES,
ACTION_TYPES,
SELECT_ENTITY,
SET_INVENTORY_FILTER,
SET_PAGINATION,
SET_ROS_TAB_VISBILITY
} from './action-types';
import systemProfileStore from './systemProfileStore';
import {
ComplianceTab,
Expand Down Expand Up @@ -64,6 +71,7 @@ function entityLoaded(state) {
(!insights.chrome.isProd || (insights.chrome.isProd && insights?.chrome?.isBeta())) && {
title: 'Resource Optimization',
name: 'ros',
isVisible: false,
component: RosTab
}
].filter(Boolean)
Expand Down Expand Up @@ -95,6 +103,17 @@ function entitySelected(state, { payload }) {
};
}

function resourceOptTabVisibility(state, { payload }) {
return {
...state,
activeApps: state.activeApps?.map((entity) => entity.name === 'ros' ? ({
...entity,
isVisible: payload
}) : entity
)
};
}

function entityDeleted(state, { meta }) {
const selected = state.selected || (new Map());
meta.systems.forEach(id => selected.delete(id));
Expand All @@ -105,11 +124,7 @@ function entityDeleted(state, { meta }) {
};
}

function onEntitiesLoaded(state, { payload, meta }) {
if (meta?.lastDateRequest < state?.lastDateRequest) {
return state;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rvsia this was added to prevent race conditions, right? I don't think we can remove this.


function onEntitiesLoaded(state, { payload }) {
return {
...state,
rows: mergeArraysByKey([state.rows, payload.results.map(result => {
Expand Down Expand Up @@ -160,7 +175,8 @@ export const tableReducer = applyReducerHash(

export const entitesDetailReducer = () => applyReducerHash(
{
[INVENTORY_ACTION_TYPES.LOAD_ENTITY_FULFILLED]: entityLoaded
[INVENTORY_ACTION_TYPES.LOAD_ENTITY_FULFILLED]: entityLoaded,
[SET_ROS_TAB_VISBILITY]: resourceOptTabVisibility
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use INVENTORY_ACTION_TYPES.LOAD_SYSTEM_PROFILE

Suggested change
[SET_ROS_TAB_VISBILITY]: resourceOptTabVisibility
[INVENTORY_ACTION_TYPES.LOAD_SYSTEM_PROFILE]: resourceOptTabVisibility

},
defaultState
);
Expand Down