[Security Solution][Endpoint] Policy Details store/routing common changes for Trusted Apps by Policy feature (#112567) (#112673)

The changes were picked from the current draft PR #112239 so that they can be shared with other changes taking place in parallel:

- Routing methods for parsing/retrieving url params for policy details page
- store selectors/reducers in support of url location management for policy details

Co-authored-by: Paul Tavares <56442535+paul-tavares@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2021-09-21 13:31:30 -04:00 committed by GitHub
parent a7d00cff7c
commit f1baa86365
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 1 deletions

View file

@ -26,6 +26,7 @@ import { appendSearch } from '../../common/components/link_to/helpers';
import { EndpointIndexUIQueryParams } from '../pages/endpoint_hosts/types';
import { TrustedAppsListPageLocation } from '../pages/trusted_apps/state';
import { EventFiltersPageLocation } from '../pages/event_filters/types';
import { PolicyDetailsArtifactsPageLocation } from '../pages/policy/types';
// Taken from: https://github.com/microsoft/TypeScript/issues/12936#issuecomment-559034150
type ExactKeys<T1, T2> = Exclude<keyof T1, keyof T2> extends never ? T1 : never;
@ -160,6 +161,25 @@ const normalizeTrustedAppsPageLocation = (
}
};
const normalizePolicyDetailsArtifactsListPageLocation = (
location?: Partial<PolicyDetailsArtifactsPageLocation>
): Partial<PolicyDetailsArtifactsPageLocation> => {
if (location) {
return {
...(!isDefaultOrMissing(location.page_index, MANAGEMENT_DEFAULT_PAGE)
? { page_index: location.page_index }
: {}),
...(!isDefaultOrMissing(location.page_size, MANAGEMENT_DEFAULT_PAGE_SIZE)
? { page_size: location.page_size }
: {}),
...(!isDefaultOrMissing(location.show, undefined) ? { show: location.show } : {}),
...(!isDefaultOrMissing(location.filter, '') ? { filter: location.filter } : ''),
};
} else {
return {};
}
};
const normalizeEventFiltersPageLocation = (
location?: Partial<EventFiltersPageLocation>
): Partial<EventFiltersPageLocation> => {
@ -257,6 +277,34 @@ export const getTrustedAppsListPath = (location?: Partial<TrustedAppsListPageLoc
)}`;
};
export const extractPolicyDetailsArtifactsListPageLocation = (
query: querystring.ParsedUrlQuery
): PolicyDetailsArtifactsPageLocation => {
const showParamValue = extractFirstParamValue(
query,
'show'
) as PolicyDetailsArtifactsPageLocation['show'];
return {
...extractListPaginationParams(query),
show: showParamValue && 'list' === showParamValue ? showParamValue : undefined,
};
};
export const getPolicyDetailsArtifactsListPath = (
policyId: string,
location?: Partial<PolicyDetailsArtifactsPageLocation>
): string => {
const path = generatePath(MANAGEMENT_ROUTING_POLICY_DETAILS_TRUSTED_APPS_PATH, {
tabName: AdministrationSubTab.policies,
policyId,
});
return `${path}${appendSearch(
querystring.stringify(normalizePolicyDetailsArtifactsListPageLocation(location))
)}`;
};
export const extractEventFiltetrsPageLocation = (
query: querystring.ParsedUrlQuery
): EventFiltersPageLocation => {

View file

@ -5,6 +5,8 @@
* 2.0.
*/
// eslint-disable-next-line import/no-nodejs-modules
import { parse } from 'querystring';
import { fullPolicy, isOnPolicyDetailsPage, license } from './selectors';
import {
Immutable,
@ -15,6 +17,12 @@ import {
import { ImmutableReducer } from '../../../../../common/store';
import { AppAction } from '../../../../../common/store/actions';
import { PolicyDetailsState } from '../../types';
import {
MANAGEMENT_DEFAULT_PAGE,
MANAGEMENT_DEFAULT_PAGE_SIZE,
} from '../../../../common/constants';
import { extractPolicyDetailsArtifactsListPageLocation } from '../../../../common/routing';
import { createUninitialisedResourceState } from '../../../../state';
const updatePolicyConfigInPolicyData = (
policyData: Immutable<PolicyData>,
@ -47,6 +55,15 @@ export const initialPolicyDetailsState: () => Immutable<PolicyDetailsState> = ()
total: 0,
other: 0,
},
artifacts: {
location: {
page_index: MANAGEMENT_DEFAULT_PAGE,
page_size: MANAGEMENT_DEFAULT_PAGE_SIZE,
show: undefined,
filter: '',
},
availableList: createUninitialisedResourceState(),
},
});
export const policyDetailsReducer: ImmutableReducer<PolicyDetailsState, AppAction> = (
@ -106,6 +123,12 @@ export const policyDetailsReducer: ImmutableReducer<PolicyDetailsState, AppActio
const newState: Immutable<PolicyDetailsState> = {
...state,
location: action.payload,
artifacts: {
...state.artifacts,
location: extractPolicyDetailsArtifactsListPageLocation(
parse(action.payload.search.slice(1))
),
},
};
const isCurrentlyOnDetailsPage = isOnPolicyDetailsPage(newState);
const wasPreviouslyOnDetailsPage = isOnPolicyDetailsPage(state);

View file

@ -9,7 +9,7 @@ import { createSelector } from 'reselect';
import { matchPath } from 'react-router-dom';
import { ILicense } from '../../../../../../../licensing/common/types';
import { unsetPolicyFeaturesAccordingToLicenseLevel } from '../../../../../../common/license/policy_config';
import { PolicyDetailsState } from '../../types';
import { PolicyDetailsArtifactsPageLocation, PolicyDetailsState } from '../../types';
import {
Immutable,
NewPolicyData,
@ -80,6 +80,13 @@ export const needsToRefresh = (state: Immutable<PolicyDetailsState>): boolean =>
return !state.policyItem && !state.apiError;
};
/**
* Returns current artifacts location
*/
export const getCurrentArtifactsLocation = (
state: Immutable<PolicyDetailsState>
): Immutable<PolicyDetailsArtifactsPageLocation> => state.artifacts.location;
/** Returns a boolean of whether the user is on the policy form page or not */
export const isOnPolicyFormPage = (state: Immutable<PolicyDetailsState>) => {
return (

View file

@ -21,6 +21,8 @@ import {
GetPackagesResponse,
UpdatePackagePolicyResponse,
} from '../../../../../fleet/common';
import { AsyncResourceState } from '../../state';
import { TrustedAppsListData } from '../trusted_apps/state';
/**
* Policy list store state
@ -61,6 +63,8 @@ export interface PolicyDetailsState {
isLoading: boolean;
/** current location of the application */
location?: Immutable<AppLocation>;
/** artifacts namespace inside policy details page */
artifacts: PolicyArtifactsState;
/** A summary of stats for the agents associated with a given Fleet Agent Policy */
agentStatusSummary?: Omit<GetAgentStatusResponse['results'], 'updating'>;
/** Status of an update to the policy */
@ -72,12 +76,29 @@ export interface PolicyDetailsState {
license?: ILicense;
}
/**
* Policy artifacts store state
*/
export interface PolicyArtifactsState {
/** artifacts location params */
location: PolicyDetailsArtifactsPageLocation;
/** A list of artifacts can be linked to the policy */
availableList: AsyncResourceState<TrustedAppsListData>;
}
export enum OS {
windows = 'windows',
mac = 'mac',
linux = 'linux',
}
export interface PolicyDetailsArtifactsPageLocation {
page_index: number;
page_size: number;
show?: 'list';
filter: string;
}
/**
* Returns the keys of an object whose values meet a criteria.
* Ex) interface largeNestedObject = {