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

Merge 4.9.1 into 4.10.0 #7105

Merged
merged 4 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Removed GET /elastic/statistics API endpoint [#7001](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7001)
- Removed VirusTotal application in favor of Malware Detection [#7038](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7038)

## Wazuh v4.9.1 - OpenSearch Dashboards 2.13.0 - Revision 03
## Wazuh v4.9.1 - OpenSearch Dashboards 2.13.0 - Revision 04

### Added

Expand All @@ -64,6 +64,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Fixed style when unnpinned an agent in endpoint summary section [#7015](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7015)
- Fixed overflow style on a long value filter [#7021](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7021)
- Fixed buttons enabled for a readonly user in `Endpoint groups` section [#7056](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7056)
- Fixed the automatic page refresh in dashboards and prevent duplicate requests [#7090](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7090)

### Changed

Expand All @@ -79,6 +80,7 @@ All notable changes to the Wazuh app project will be documented in this file.

- Removed the PDF report footer year [#7023](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7023)
- Removed the XML autoformat function group configuration due to performance [#6999](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6999)
- Removed data grid tables from Threat hunting dashboard, GitHub panel and Office365 panel [#7086](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7086)

## Wazuh v4.9.0 - OpenSearch Dashboards 2.13.0 - Revision 07

Expand Down
3 changes: 3 additions & 0 deletions plugins/main/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,6 @@ export const SEARCH_BAR_DEBOUNCE_UPDATE_TIME = 400;

// ID used to refer the createOsdUrlStateStorage state
export const OSD_URL_STATE_STORAGE_ID = 'state:storeInSessionStorage';

export const APP_STATE_URL_KEY = '_a';
export const GLOBAL_STATE_URL_KEY = '_g';
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,6 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => {
onChangeItemsPerPage: onChangeItemsPerPage,
onChangePage: onChangePage,
},
setPagination,
} as EuiDataGridProps;
};
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ export function useDataSource<
const {
filters: initialFilters = [...defaultFilters],
fetchFilters: initialFetchFilters = [],
fixedFilters: initialFixedFilters = [],
DataSource: DataSourceConstructor,
repository,
factory: injectedFactory,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const SAVED_QUERY = 'savedQuery';
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { useState, useEffect } from 'react';
import {
DataPublicPluginStart,
RefreshInterval,
SavedQuery,
TimeRange,
Query,
Filter,
} from '../../../../../../../src/plugins/data/public';
import NavigationService from '../../../../react-services/navigation-service';
import { OSD_URL_STATE_STORAGE_ID } from '../../../../../common/constants';
import { getDataPlugin, getUiSettings } from '../../../../kibana-services';
import { createOsdUrlStateStorage } from '../../../../../../../src/plugins/opensearch_dashboards_utils/public';
import OsdUrlStateStorage from '../../../../react-services/state-storage';

interface Options {
firstTime?: boolean;
}

interface UseSavedQueriesProps {
queryService: DataPublicPluginStart['query'];
setTimeFilter: (timeFilter: TimeRange) => void;
setRefreshInterval: (refreshInterval: RefreshInterval) => void;
setQuery: (query?: Query) => void;
setFilters: (filters: Filter[]) => void;
}

interface UseSavedQueriesReturn {
savedQuery?: SavedQuery;
setSavedQuery: (savedQuery: SavedQuery) => void;
clearSavedQuery: () => void;
}

export const useSavedQuery = (
props: UseSavedQueriesProps,
): UseSavedQueriesReturn => {
// Handle saved queries
const [savedQuery, setSavedQuery] = useState<SavedQuery | undefined>();
const data = getDataPlugin();
const config = getUiSettings();
const history = NavigationService.getInstance().getHistory();
const osdUrlStateStorage = createOsdUrlStateStorage({
useHash: config.get(OSD_URL_STATE_STORAGE_ID),
history: history,
});

const getAppFilters = (
newSavedQuery?: SavedQuery,
{ firstTime }: Options = { firstTime: false },
) => {
const { filterManager } = props.queryService;
// When the page reloads, savedQuery starts as undefined, so retrieve the time and refreshInterval from the URL.
return firstTime
? filterManager.getAppFilters()
: newSavedQuery?.attributes.filters ?? [];
};

const getQuery = (
newSavedQuery?: SavedQuery,
{ firstTime }: Options = { firstTime: false },
) => {
const { queryString } = props.queryService;
// When the page reloads, savedQuery starts as undefined, so retrieve the time and refreshInterval from the URL.
return firstTime
? queryString.getQuery()
: newSavedQuery?.attributes.query ?? { query: '', language: 'kuery' };
};

const getTimeFilter = (
newSavedQuery?: SavedQuery,
{ firstTime }: Options = { firstTime: false },
) => {
const { timefilter } = props.queryService;
// When the page reloads, savedQuery starts as undefined, so retrieve the time and refreshInterval from the URL.
return firstTime
? timefilter.timefilter.getTime()
: newSavedQuery?.attributes.timefilter;
};

const getRefreshInterval = (
newSavedQuery?: SavedQuery,
{ firstTime }: Options = { firstTime: false },
) => {
const { timefilter } = props.queryService;
// When the page reloads, savedQuery starts as undefined, so retrieve the time and refreshInterval from the URL.
return firstTime
? timefilter.timefilter.getRefreshInterval()
: newSavedQuery?.attributes.timefilter?.refreshInterval;
};

const setTimeFilter = (timeFilter: TimeRange) => {
props.setTimeFilter(timeFilter);
props.queryService.timefilter.timefilter.setTime(timeFilter);
};

const saveSavedQuery = async (
newSavedQuery?: SavedQuery,
{ firstTime }: Options = { firstTime: false },
) => {
setSavedQuery(newSavedQuery);
const filters = getAppFilters(newSavedQuery, { firstTime });
const query = getQuery(newSavedQuery, { firstTime });
await OsdUrlStateStorage(data, osdUrlStateStorage).replaceUrlAppState({
savedQuery: newSavedQuery?.id,
});
props.setFilters(filters);
props.setQuery(query);
if (newSavedQuery?.attributes.timefilter) {
setTimeFilter(getTimeFilter(newSavedQuery, { firstTime }));
props.setRefreshInterval(
getRefreshInterval(newSavedQuery, { firstTime }),
);
}
};

const updateSavedQuery = async (
savedQuery: SavedQuery,
{ firstTime }: { firstTime?: boolean } = { firstTime: false },
) => {
saveSavedQuery(savedQuery, { firstTime });
};

const clearSavedQuery = () => {
// remove saved query from url
saveSavedQuery(undefined);
};

// Effect is used to convert a saved query id into an object
useEffect(() => {
const fetchSavedQuery = async () => {
try {
const savedQueryId = OsdUrlStateStorage(
data,
osdUrlStateStorage,
).getAppStateFromUrl().savedQuery as string;
if (!savedQueryId) return;
// fetch saved query
const savedQuery = await props.queryService.savedQueries.getSavedQuery(
savedQueryId,
);
updateSavedQuery(savedQuery, { firstTime: true });
} catch (error) {
clearSavedQuery();
}
};

fetchSavedQuery();
}, [props.queryService, props.queryService.savedQueries]);

return {
savedQuery,
setSavedQuery: updateSavedQuery,
clearSavedQuery,
};
};
17 changes: 16 additions & 1 deletion plugins/main/public/components/common/hooks/use-time-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,30 @@ export function useTimeFilter() {
const [timeFilter, setTimeFilter] = useState(
globalStateFromUrl?.time ?? timefilter.getTime(),
);
const [refreshInterval, setRefreshInterval] = useState(
globalStateFromUrl?.refreshInterval ?? timefilter.getRefreshInterval(),
);
const [timeHistory, setTimeHistory] = useState(timefilter._history);
useEffect(() => {
const subscription = timefilter.getTimeUpdate$().subscribe(() => {
setTimeFilter(timefilter.getTime());
setTimeHistory(timefilter._history);
});
const subscriptionRefreshInterval = timefilter
.getRefreshIntervalUpdate$()
.subscribe(() => {
setRefreshInterval(timefilter.getRefreshInterval());
});
return () => {
subscription.unsubscribe();
subscriptionRefreshInterval.unsubscribe();
};
}, []);
return { timeFilter, setTimeFilter: timefilter.setTime, timeHistory };
return {
timeFilter,
setTimeFilter: timefilter.setTime,
refreshInterval,
setRefreshInterval: timefilter.setRefreshInterval,
timeHistory,
};
}
17 changes: 9 additions & 8 deletions plugins/main/public/components/common/permissions/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ import {
EuiButtonEmpty,
EuiButtonIcon,
EuiLink,
EuiButtonProps,
} from '@elastic/eui';

import { IWzElementPermissionsProps, WzElementPermissions } from './element';

interface IWzButtonPermissionsProps
extends Omit<
IWzElementPermissionsProps,
'children' | 'additionalPropsFunction'
> {
buttonType?: 'default' | 'empty' | 'icon' | 'link' | 'switch';
rest: any;
}
type IWzButtonPermissionsProps = Omit<
IWzElementPermissionsProps,
'children' | 'additionalPropsFunction'
> &
React.ButtonHTMLAttributes<HTMLButtonElement> &
EuiButtonProps & {
buttonType?: 'default' | 'empty' | 'icon' | 'link' | 'switch';
};

export const WzButtonPermissions = ({
buttonType = 'default',
Expand Down
10 changes: 9 additions & 1 deletion plugins/main/public/components/common/search-bar/search-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ export interface WzSearchBarProps extends SearchBarProps {
postFilters?: React.ReactElement;
postFixedFilters?: () => React.ReactElement<any>[];
hideFixedFilters?: boolean;
showSaveQueryButton?: boolean;
showSaveQuery?: boolean;
}

export const WzSearchBar = ({
fixedFilters = [],
postFixedFilters,
showSaveQueryButton = true,
showSaveQuery = true,
preQueryBar,
hideFixedFilters,
postFilters,
Expand Down Expand Up @@ -52,7 +56,11 @@ export const WzSearchBar = ({
>
{preQueryBar ? <EuiFlexItem>{preQueryBar}</EuiFlexItem> : null}
<EuiFlexItem grow={!preQueryBar}>
<SearchBar {...restProps} />
<SearchBar
{...restProps}
showFilterBar={showSaveQueryButton}
showSaveQuery={showSaveQuery}
/>
</EuiFlexItem>
</EuiFlexGroup>
) : null}
Expand Down
Loading
Loading