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

[Cloud Security] add compliance dashboard ui tab persistence #173853

Merged

Conversation

Omolola-Akinleye
Copy link
Contributor

@Omolola-Akinleye Omolola-Akinleye commented Dec 21, 2023

Summary

Summarize your PR. If it involves visual changes include a screenshot or gif.

Add UI tab persistence to the Compliance Dashboard. The selected posture type tab is persisted in local storage. Here are some of the test cases for Compliance Dashboard Tab Persistence.

  • Test case: Changing url in the same tab will persist tab
  • Test case: Logging in and out of Kibana and going a back to Kibana will persist tab
  • Test Case: Navigating to Cloud Security Dashboard within Kibana will persist tab
  • Test Case: Dashboard recovery mode witching from the onboarding state to generating a Dashboard with findings still works and tab will persist.
  • Test Case: Refreshing url tab continues to persist.
  • Test Case: If no tab is selected, then CSPM dashboard will show.
  • Test Case: Redirect subscribes to the persisted selected tab in the url.
Screen.Recording.2023-12-21.at.11.06.10.AM.mov

@Omolola-Akinleye Omolola-Akinleye added release_note:skip Skip the PR/issue when compiling release notes Team:Cloud Security Cloud Security team related v8.13.0 labels Dec 21, 2023
@Omolola-Akinleye Omolola-Akinleye self-assigned this Dec 21, 2023
@Omolola-Akinleye Omolola-Akinleye marked this pull request as ready for review December 21, 2023 16:47
@Omolola-Akinleye Omolola-Akinleye requested a review from a team as a code owner December 21, 2023 16:47
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-cloud-security-posture (Team:Cloud Security)

Comment on lines 309 to 334
<Routes>
<Route
exact
path={cloudPosturePages.dashboard.path}
render={() => <DashboardTabRedirecter lastTabSelected={selectedPostureTypeTab} />}
/>
<Route path={cloudPosturePages.cspm_dashboard.path}>
<IntegrationPostureDashboard
dashboardType={policyTemplate}
complianceData={getDashboardData.data}
notInstalledConfig={getNotInstalledConfig(policyTemplate, integrationLink)}
isIntegrationInstalled={setupStatus !== 'not-installed'}
/>
</Route>

<Route path={cloudPosturePages.kspm_dashboard.path}>
<IntegrationPostureDashboard
dashboardType={policyTemplate}
complianceData={getDashboardData.data}
notInstalledConfig={getNotInstalledConfig(policyTemplate, integrationLink)}
isIntegrationInstalled={setupStatus !== 'not-installed'}
/>
</Route>
{/* Redirect to default cspm dashboard if no match */}
<Route path="*" render={() => <Redirect to={cloudPosturePages.cspm_dashboard.path} />} />
</Routes>
Copy link
Contributor

Choose a reason for hiding this comment

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

Following my previous comment, I think any routing logic should be handled by the parent

Copy link
Contributor Author

@Omolola-Akinleye Omolola-Akinleye Jan 2, 2024

Choose a reason for hiding this comment

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

@opauloh The only challenge here is the effort and potential side effects of moving routing logic from the TabContent component to ComplianceDashboard. Compliance Dashboard Component has useEffect concerned with getDefaultTab, and list a number of dependencies also feature in TabContent Component.

useEffect(() => {
    if (selectedTabLocalStorage) {
      return;
    }

    const preferredDashboard = getDefaultTab(
      getSetupStatus,
      getCspmDashboardData.data,
      getKspmDashboardData.data
    );
    setSelectedTabLocalStorage(preferredDashboard);
  }, [
    getCspmDashboardData.data,
    selectedTabLocalStorage,
    setSelectedTabLocalStorage,
    getCspmDashboardData.data?.stats.totalFindings,
    getKspmDashboardData.data,
    getKspmDashboardData.data?.stats.totalFindings,
    getSetupStatus,
    getSetupStatus?.cspm?.status,
    getSetupStatus?.kspm?.status,
  ]);

The TabContent component's routing logic currently has a re-fetching dependency listening to prop and then proceeds to fetch status and dashboard data until there are findings.

@Omolola-Akinleye Omolola-Akinleye requested a review from a team as a code owner January 29, 2024 17:21
@dmlemeshko dmlemeshko removed the request for review from a team February 9, 2024 08:47
@dmlemeshko
Copy link
Member

I removed appex-qa review since journey changes were reverted.

@Omolola-Akinleye
Copy link
Contributor Author

@dmlemeshko Thanks!

@kfirpeled kfirpeled dismissed their stale review February 11, 2024 18:20

LGTM, waits for Paulo approval

Copy link
Contributor

@opauloh opauloh left a comment

Choose a reason for hiding this comment

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

Tested locally, the URL params changes seem ok, but I noticed that when navigating back to the Dashboard from the application itself it will always open the Dashboard in the Cloud tab instead of the previous Tab selected by the user.

Screen.Recording.2024-02-12.at.12.14.19.PM.mov

This is by design, or it's missing the local storage persistence? I ask because the original ticket #148435 asks for persisting in the local storage.

? [
{
label: i18n.translate('xpack.csp.dashboardTabs.cloudTab.tabTitle', {
defaultMessage: 'Cloud',
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this point to CSPM_DASHBOARD_TAB_NAME?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe since we are using translation, we just preserve the default text message. Cloud and Kubernetes. I don't know if it's necessary to add a parameter since we are only using one word.

},
{
label: i18n.translate('xpack.csp.dashboardTabs.kubernetesTab.tabTitle', {
defaultMessage: 'Kubernetes',
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this point to KSPM_DASHBOARD_TAB_NAME

@@ -48,6 +48,8 @@ export const LOCAL_STORAGE_DASHBOARD_CLUSTER_SORT_KEY =
export const LOCAL_STORAGE_DASHBOARD_BENCHMARK_SORT_KEY =
'cloudPosture:complianceDashboard:benchmarkSort';
export const LOCAL_STORAGE_FINDINGS_LAST_SELECTED_TAB_KEY = 'cloudPosture:findings:lastSelectedTab';
export const LOCAL_STORAGE_COMPLIANCE_DASHBOARD_SELECTED_TAB_KEY =
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems this constant is declared but is not being reused elsewhere

Copy link
Contributor Author

@Omolola-Akinleye Omolola-Akinleye Feb 12, 2024

Choose a reason for hiding this comment

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

Thanks! I'll remove that!

@Omolola-Akinleye
Copy link
Contributor Author

Tested locally, the URL params changes seem ok, but I noticed that when navigating back to the Dashboard from the application itself it will always open the Dashboard in the Cloud tab instead of the previous Tab selected by the user.

Screen.Recording.2024-02-12.at.12.14.19.PM.mov
This is by design, or it's missing the local storage persistence? I ask because the original ticket #148435 asks for persisting in the local storage.

Yes the original ticket asked for local storage, but talked it over with @kfirpeled, and local storage was redundant and not utilized as common practice for routing with tabs in Kibana.

Copy link
Contributor

@opauloh opauloh left a comment

Choose a reason for hiding this comment

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

LGTM, just some minor comments

@Omolola-Akinleye Omolola-Akinleye enabled auto-merge (squash) February 12, 2024 22:46
@Omolola-Akinleye Omolola-Akinleye requested a review from a team February 13, 2024 15:51
Comment on lines 315 to 316
{/* Redirect to default cspm dashboard if no match */}
{/* <Route path="*" render={() => <Redirect to={cloudPosturePages.cspm_dashboard.path} />} />*/}
Copy link
Contributor

Choose a reason for hiding this comment

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

looks to be missing from code

Copy link
Contributor Author

@Omolola-Akinleye Omolola-Akinleye Feb 13, 2024

Choose a reason for hiding this comment

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

Thanks! I will address the following code in follow-up PR. I want to push PR before FF

Comment on lines +204 to +206
if (!cspmStats || !pluginStatus) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't kspmStats be checked as well?
what happens of the one of those calls failed? do we get an empty screen or the error log?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When first routing to Dashboard page, CSPM stats and KSPM stats are undefined. There is no need to check if kspmStats are defined. This check helps resolves race condition when we are waiting for cspm stats and kspm stats to be defined then show the correct tabs based on plugin status, cspm and kspm status.

Comment on lines +339 to +340
if (location.pathname === cloudPosturePages.kspm_dashboard.path) {
tab = POSTURE_TYPE_KSPM;
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 also add the postureType as an optional parameter to the default url, and then check the value with useParams of react-router

example

Comment on lines +360 to +364
search: encodeQuery({
// Set query language from user's preference
query: services.data.query.queryString.getDefaultQuery(),
filters: services.data.query.filterManager.getFilters(),
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need those filters/queries on the dashboard?

Copy link
Contributor Author

@Omolola-Akinleye Omolola-Akinleye Feb 13, 2024

Choose a reason for hiding this comment

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

This preserves filters/queries on the dashboard when clicking on each Tab. We are preserving the filters and queries when clicking tabs and routing between tabs. We are keeping the url consistent with filters/queries similar practice across Kibana.

);

const tabs = useMemo(() => {
const navigateToPostureTypeDashboardTab = (pathname: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

this should probably be a hook in a separate, file next to use_navigate_findings
but also navigateToPostureTypeDashboardTab is just a nav to what ever path is being passed to it. which makes it a bit random. i would recommand to change the implementation for something like:

const navigateToPostureTypeDashboardTab = (postureType: 'kspm' | 'cspm') => {
   history.push(
      generatePath(benchmarksNavigation.rules.path, {
        postureType // this is assuming you are adding the postureType as optional param to the path, but if not you can also just do an "if" and navigate to the selected tab based on the value of postureType
      })
    );
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried use_navigate_findings pattern hooks. TabContent onClick Handler behaves differently than React.jsx element click handler. onclick does support hook being called

Comment on lines 51 to 56
const shouldSkip = true;

if (!shouldSkip) {
await page.goto(kbnUrl.get(`/app/security/cloud_security_posture/dashboard`));
await page.waitForSelector(subj('csp:dashboard-sections-table-header-score'));
}
Copy link
Member

Choose a reason for hiding this comment

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

Could you explain this change? If the step is redundant, I suggest to remove it.
But if it is temporary fix, adding a comment would be a good thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was attempting to skip the test. I will just comment out the code and add a comment! Thank you.

Copy link
Member

@dmlemeshko dmlemeshko left a comment

Choose a reason for hiding this comment

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

journey update LGTM

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
cloudSecurityPosture 412.2KB 412.7KB +485.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
cloudSecurityPosture 15.8KB 16.0KB +209.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @Omolola-Akinleye

@Omolola-Akinleye Omolola-Akinleye merged commit 06d4b3e into elastic:main Feb 13, 2024
16 checks passed
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Feb 13, 2024
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
…#173853)

## Summary

Summarize your PR. If it involves visual changes include a screenshot or
gif.

Add UI tab persistence to the Compliance Dashboard. The selected posture
type tab is persisted in local storage. Here are some of the test cases
for Compliance Dashboard Tab Persistence.
- Test case: Changing url in the same tab  will persist tab
- Test case: Logging in and out of Kibana and going a back to Kibana
will persist tab
- Test Case: Navigating to Cloud Security Dashboard within Kibana will
persist tab
- Test Case: Dashboard recovery mode witching from the onboarding state
to generating a Dashboard with findings still works and tab will
persist.
-  Test Case: Refreshing url tab continues to persist.
-  Test Case: If no tab is selected, then CSPM dashboard will show.
- Test Case: Redirect subscribes to the persisted selected tab in the
url.




https://github.com/elastic/kibana/assets/17135495/1ce156f6-6d0c-4436-be78-d76aba19e8f5
CoenWarmer pushed a commit to CoenWarmer/kibana that referenced this pull request Feb 15, 2024
…#173853)

## Summary

Summarize your PR. If it involves visual changes include a screenshot or
gif.

Add UI tab persistence to the Compliance Dashboard. The selected posture
type tab is persisted in local storage. Here are some of the test cases
for Compliance Dashboard Tab Persistence.
- Test case: Changing url in the same tab  will persist tab
- Test case: Logging in and out of Kibana and going a back to Kibana
will persist tab
- Test Case: Navigating to Cloud Security Dashboard within Kibana will
persist tab
- Test Case: Dashboard recovery mode witching from the onboarding state
to generating a Dashboard with findings still works and tab will
persist.
-  Test Case: Refreshing url tab continues to persist.
-  Test Case: If no tab is selected, then CSPM dashboard will show.
- Test Case: Redirect subscribes to the persisted selected tab in the
url.




https://github.com/elastic/kibana/assets/17135495/1ce156f6-6d0c-4436-be78-d76aba19e8f5
fkanout pushed a commit to fkanout/kibana that referenced this pull request Mar 4, 2024
…#173853)

## Summary

Summarize your PR. If it involves visual changes include a screenshot or
gif.

Add UI tab persistence to the Compliance Dashboard. The selected posture
type tab is persisted in local storage. Here are some of the test cases
for Compliance Dashboard Tab Persistence.
- Test case: Changing url in the same tab  will persist tab
- Test case: Logging in and out of Kibana and going a back to Kibana
will persist tab
- Test Case: Navigating to Cloud Security Dashboard within Kibana will
persist tab
- Test Case: Dashboard recovery mode witching from the onboarding state
to generating a Dashboard with findings still works and tab will
persist.
-  Test Case: Refreshing url tab continues to persist.
-  Test Case: If no tab is selected, then CSPM dashboard will show.
- Test Case: Redirect subscribes to the persisted selected tab in the
url.




https://github.com/elastic/kibana/assets/17135495/1ce156f6-6d0c-4436-be78-d76aba19e8f5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Cloud Security Cloud Security team related v8.13.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Cloud Security] Misconfiguration - Multiple integration support - selected tab to be URL based
8 participants