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

The check update button does not show the date of the last scan #6328

Merged
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ All notable changes to the Wazuh app project will be documented in this file.
### Added

- Support for Wazuh 4.8.0
- Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256)
- Added the ability to check if there are available updates from the UI. [#6093](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6093) [#6256](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6256) [#6328](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6328)
- Added remember server address check [#5791](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5791)
- Added the ssl_agent_ca configuration to the SSL Settings form [#6083](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6083)
- Added global vulnerabilities dashboards [#5896](https://github.com/wazuh/wazuh-dashboard-plugins/pull/5896) [#6179](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6179) [#6173](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6173) [#6147](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6147) [#6231](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6231) [#6246](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6246) [#6321](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6321) [#6338] (https://github.com/wazuh/wazuh-dashboard-plugins/pull/6338)
Expand Down
5 changes: 3 additions & 2 deletions plugins/main/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"opensearchDashboardsReact",
"opensearchDashboardsUtils",
"opensearchDashboardsLegacy",
"wazuhCheckUpdates"
"wazuhCheckUpdates",
"wazuhCore"
],
"optionalPlugins": [
"security",
Expand All @@ -29,4 +30,4 @@
],
"server": true,
"ui": true
}
}
20 changes: 8 additions & 12 deletions plugins/main/public/components/settings/api/api-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ import { compose } from 'redux';
import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types';
import { UI_LOGGER_LEVELS } from '../../../../common/constants';
import { getErrorOrchestrator } from '../../../react-services/common-services';
import { getWazuhCheckUpdatesPlugin } from '../../../kibana-services';
import {
getWazuhCheckUpdatesPlugin,
getWazuhCorePlugin,
} from '../../../kibana-services';
import { AvailableUpdatesFlyout } from './available-updates-flyout';
import { formatUIDate } from '../../../react-services/time-service';

export const ApiTable = compose(
withErrorBoundary,
Expand All @@ -47,13 +49,10 @@ export const ApiTable = compose(
constructor(props) {
super(props);

const { getAvailableUpdates } = getWazuhCheckUpdatesPlugin();

this.state = {
apiEntries: [],
refreshingEntries: false,
availableUpdates: {},
getAvailableUpdates,
refreshingAvailableUpdates: true,
apiAvailableUpdateDetails: undefined,
};
Expand All @@ -62,9 +61,8 @@ export const ApiTable = compose(
async getApisAvailableUpdates(forceUpdate = false) {
try {
this.setState({ refreshingAvailableUpdates: true });
const availableUpdates = await this.state.getAvailableUpdates(
forceUpdate,
);
const availableUpdates =
await getWazuhCheckUpdatesPlugin().getAvailableUpdates(forceUpdate);
this.setState({ availableUpdates });
} catch (error) {
const options = {
Expand Down Expand Up @@ -553,10 +551,8 @@ export const ApiTable = compose(
title='Last check'
content={
this.state.availableUpdates?.last_check_date
? formatUIDate(
new Date(
this.state.availableUpdates.last_check_date,
),
? getWazuhCorePlugin().utils.formatUIDate(
this.state.availableUpdates.last_check_date,
)
: '-'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,29 @@ jest.mock(
'../../../../../../../node_modules/@elastic/eui/lib/services/accessibility/html_id_generator',
() => ({
htmlIdGenerator: () => () => 'htmlId',
})
}),
);

jest.mock('../../../../react-services/time-service', () => ({
formatUIDate: jest.fn().mockReturnValue('Sep 25, 2023 @ 14:03:40.816'),
jest.mock('../../../../kibana-services', () => ({
getWazuhCorePlugin: jest.fn().mockReturnValue({
utils: {
formatUIDate: jest.fn().mockReturnValue('Sep 25, 2023 @ 14:03:40.816'),
},
}),
}));

jest.mock('../../../../../../../src/plugins/opensearch_dashboards_react/public', () => ({
Markdown: jest.fn().mockReturnValue(<div>Description</div>),
}));
jest.mock(
'../../../../../../../src/plugins/opensearch_dashboards_react/public',
() => ({
Markdown: jest.fn().mockReturnValue(<div>Description</div>),
}),
);

describe('UpdateDetail component', () => {
test('should return the UpdateDetail component', async () => {
const { container, getByText, getByRole } = render(
<UpdateDetail
type="Last available minor"
type='Last available minor'
update={{
description:
'## Manager\r\n\r\n### Fixed\r\n\r\n- Fixed a crash when overwrite rules are triggered...',
Expand All @@ -35,7 +42,7 @@ describe('UpdateDetail component', () => {
tag: 'v4.8.0',
title: 'Wazuh v4.8.0',
}}
/>
/>,
);

expect(container).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { Update } from '../../../../../../wazuh-check-updates/common/types';
import { formatUIDate } from '../../../../react-services/time-service';
import { Markdown } from '../../../../../../../src/plugins/opensearch_dashboards_react/public';
import {
EuiAccordion,
Expand All @@ -12,6 +11,7 @@ import {
EuiBadge,
EuiTitle,
} from '@elastic/eui';
import { getWazuhCorePlugin } from '../../../../kibana-services';

interface UpdateDetailProps {
update: Partial<Update>;
Expand All @@ -25,7 +25,9 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => {
semver?.major &&
(semver?.minor || semver?.minor === 0) &&
(semver?.patch || semver?.patch === 0);
const minorVersion = hasVersions ? `${semver.major}.${semver.minor}` : undefined;
const minorVersion = hasVersions
? `${semver.major}.${semver.minor}`
: undefined;
const releaseNotesUrl = hasVersions
? `https://documentation.wazuh.com/current/release-notes/release-${semver.major}-${semver.minor}-${semver.patch}.html`
: undefined;
Expand All @@ -36,29 +38,30 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => {
return title && tag ? (
<EuiAccordion
id={tag}
className="euiAccordionForm"
buttonClassName="euiAccordionForm__button"
className='euiAccordionForm'
buttonClassName='euiAccordionForm__button'
buttonContent={
<EuiFlexGroup alignItems="center" responsive={false}>
<EuiFlexGroup alignItems='center' responsive={false}>
<EuiFlexItem grow={false}>
<EuiTitle size="s" className="euiAccordionForm__title">
<EuiTitle size='s' className='euiAccordionForm__title'>
<h3>{title}</h3>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiBadge color="hollow">{type}</EuiBadge>
<EuiBadge color='hollow'>{type}</EuiBadge>
</EuiFlexItem>
</EuiFlexGroup>
}
paddingSize="l"
paddingSize='l'
>
{published_date ? (
<>
<EuiDescriptionList
listItems={[
{
title: 'Published',
description: formatUIDate(new Date(published_date)),
description:
getWazuhCorePlugin().utils.formatUIDate(published_date),
},
]}
/>
Expand All @@ -69,20 +72,22 @@ export const UpdateDetail = ({ update, type }: UpdateDetailProps) => {
<>
<EuiFlexGroup responsive={false} wrap>
<EuiFlexItem grow={false} style={{ maxWidth: 'max-content' }}>
<EuiLink href={releaseNotesUrl} target="_blank" external>
<EuiLink href={releaseNotesUrl} target='_blank' external>
Release notes
</EuiLink>
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ maxWidth: 'max-content' }}>
<EuiLink href={upgradeGuideUrl} target="_blank" external>
<EuiLink href={upgradeGuideUrl} target='_blank' external>
Upgrade guide
</EuiLink>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
</>
) : null}
{description ? <Markdown markdown={description} openLinksInNewTab /> : null}
{description ? (
<Markdown markdown={description} openLinksInNewTab />
) : null}
</EuiAccordion>
) : null;
};
2 changes: 2 additions & 0 deletions plugins/main/public/kibana-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const [getWzCurrentAppID, setWzCurrentAppID] =
createGetterSetter<NavigationPublicPluginStart>('WzCurrentAppID');
export const [getWazuhCheckUpdatesPlugin, setWazuhCheckUpdatesPlugin] =
createGetterSetter<WazuhCheckUpdatesPluginStart>('WazuhCheckUpdatesPlugin');
export const [getWazuhCorePlugin, setWazuhCorePlugin] =
createGetterSetter<WazuhCheckUpdatesPluginStart>('WazuhCorePlugin');
export const [getHeaderActionMenuMounter, setHeaderActionMenuMounter] =
createGetterSetter<AppMountParameters['setHeaderActionMenu']>(
'headerActionMenuMounter',
Expand Down
2 changes: 2 additions & 0 deletions plugins/main/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
setWzCurrentAppID,
setWazuhCheckUpdatesPlugin,
setHeaderActionMenuMounter,
setWazuhCorePlugin,
} from './kibana-services';
import {
AppPluginStartDependencies,
Expand Down Expand Up @@ -225,6 +226,7 @@ export class WazuhPlugin
setOverlays(core.overlays);
setErrorOrchestrator(ErrorOrchestratorService);
setWazuhCheckUpdatesPlugin(plugins.wazuhCheckUpdates);
setWazuhCorePlugin(plugins.wazuhCore);
return {};
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
.euiBody--hasFlyout {
.wz-check-updates-bottom-bar {
margin-left: 320px;
}

&.euiBody-hasOverlayMask {
.wz-check-updates-bottom-bar {
margin-left: 0px;
}
}
}
.wz-check-updates-bottom-bar {
margin-left: 320px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ jest.mock('../plugin-services', () => ({
},
},
}),
getWazuhCore: jest.fn().mockReturnValue({
hooks: {
useDockedSideNav: () => false,
},
}),
}));

jest.mock('react-use/lib/useObservable', () => () => {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import React, { useEffect, useState } from 'react';
import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
import { useUserPreferences } from '../hooks';
import { areThereNewUpdates } from '../utils';
import { getCore } from '../plugin-services';
import { getCore, getWazuhCore } from '../plugin-services';
import { AvailableUpdates } from '../../../wazuh-check-updates/common/types';
import { getAvailableUpdates } from '../services';
import { RedirectAppLinks } from '../../../../src/plugins/opensearch_dashboards_react/public';
Expand All @@ -22,6 +22,8 @@ export const UpdatesNotification = () => {
const [isDismissed, setIsDismissed] = useState(false);
const [dismissFutureUpdates, setDismissFutureUpdates] = useState(false);

const sideNavDocked = getWazuhCore().hooks.useDockedSideNav();

const {
userPreferences,
error: userPreferencesError,
Expand Down Expand Up @@ -57,7 +59,7 @@ export const UpdatesNotification = () => {

const mustNotifyUser = areThereNewUpdates(
availableUpdates?.apis_available_updates,
userPreferences.last_dismissed_updates
userPreferences.last_dismissed_updates,
);

const handleOnChangeDismiss = (checked: boolean) => {
Expand All @@ -67,7 +69,7 @@ export const UpdatesNotification = () => {
const handleOnClose = () => {
updateUserPreferences({
last_dismissed_updates: availableUpdates?.apis_available_updates?.map(
(apiAvailableUpdates) => {
apiAvailableUpdates => {
const {
api_id,
last_available_major,
Expand All @@ -80,7 +82,7 @@ export const UpdatesNotification = () => {
last_minor: last_available_minor?.tag,
last_patch: last_available_patch?.tag,
};
}
},
),
...(dismissFutureUpdates ? { hide_update_notifications: true } : {}),
});
Expand All @@ -89,55 +91,66 @@ export const UpdatesNotification = () => {

return mustNotifyUser ? (
<I18nProvider>
<EuiBottomBar className="wz-check-updates-bottom-bar">
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center" gutterSize="m">
<EuiBottomBar
className={sideNavDocked ? 'wz-check-updates-bottom-bar' : ''}
>
<EuiFlexGroup
justifyContent='spaceBetween'
alignItems='center'
gutterSize='m'
>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="m" alignItems="center">
<EuiFlexGroup gutterSize='m' alignItems='center'>
<EuiFlexItem grow={false} style={{ maxWidth: 'max-content' }}>
<EuiText>
<FormattedMessage
id="wazuhCheckUpdates.updatesNotification.message"
defaultMessage="New release is available!"
id='wazuhCheckUpdates.updatesNotification.message'
defaultMessage='New release is available!'
/>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ maxWidth: 'max-content' }}>
<RedirectAppLinks application={getCore().application}>
<EuiButtonEmpty
color="ghost"
color='ghost'
href={getCore().application.getUrlForApp('server-apis', {
path: '#/settings?tab=api',
})}
>
<FormattedMessage
id="wazuhCheckUpdates.updatesNotification.linkText"
defaultMessage="Go to the API configuration page for details"
id='wazuhCheckUpdates.updatesNotification.linkText'
defaultMessage='Go to the API configuration page for details'
/>
</EuiButtonEmpty>
</RedirectAppLinks>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="m" alignItems="center">
<EuiFlexGroup gutterSize='m' alignItems='center'>
<EuiFlexItem grow={false}>
<EuiCheckbox
id="check-dismiss-in-notification"
id='check-dismiss-in-notification'
label={
<FormattedMessage
id="wazuhCheckUpdates.updatesNotification.dismissCheckText"
defaultMessage="Disable updates notifications"
id='wazuhCheckUpdates.updatesNotification.dismissCheckText'
defaultMessage='Disable updates notifications'
/>
}
checked={dismissFutureUpdates}
onChange={(e) => handleOnChangeDismiss(e.target.checked)}
onChange={e => handleOnChangeDismiss(e.target.checked)}
/>
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ maxWidth: 'max-content' }}>
<EuiButton fill size="s" iconType="cross" onClick={() => handleOnClose()}>
<EuiButton
fill
size='s'
iconType='cross'
onClick={() => handleOnClose()}
>
<FormattedMessage
id="wazuhCheckUpdates.updatesNotification.closeButtonText"
defaultMessage="Dismiss"
id='wazuhCheckUpdates.updatesNotification.closeButtonText'
defaultMessage='Dismiss'
/>
</EuiButton>
</EuiFlexItem>
Expand Down
1 change: 1 addition & 0 deletions plugins/wazuh-core/public/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useDockedSideNav } from './use-docked-side-nav';
Loading
Loading