React version of angular license view (#111317)

* React version of angular license view

* Fix time handling and linking to license upload

* Use getPageData pattern instead of useClusters

* Add note about locked time picker

* Add disable support to monitoring toolbar

* Disable toolbar on license page only

* Remove old todo

* Clean up render setup method ordering

* Fix CI checks

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Mat Schaffer 2021-09-08 09:18:58 +09:00 committed by GitHub
parent e79a23a122
commit 7fc4c2935d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 132 additions and 5 deletions

View file

@ -11,6 +11,7 @@ import ReactDOM from 'react-dom';
import { Route, Switch, Redirect, Router } from 'react-router-dom';
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
import { LoadingPage } from './pages/loading_page';
import { LicensePage } from './pages/license_page';
import { ClusterOverview } from './pages/cluster/overview_page';
import { MonitoringStartPluginDependencies } from '../types';
import { GlobalStateProvider } from './global_state_context';
@ -53,7 +54,7 @@ const MonitoringApp: React.FC<{
<Route path="/loading" component={LoadingPage} />
<RouteInit
path="/license"
component={License}
component={LicensePage}
codePaths={['all']}
fetchAllClusters={false}
/>
@ -91,7 +92,3 @@ const NoData: React.FC<{}> = () => {
const Home: React.FC<{}> = () => {
return <div>Home page (Cluster listing)</div>;
};
const License: React.FC<{}> = () => {
return <div>License page</div>;
};

View file

@ -0,0 +1,124 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useContext, useState, useCallback, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import moment from 'moment-timezone';
import { PageTemplate } from './page_template';
import { License } from '../../components';
import { GlobalStateContext } from '../global_state_context';
import { CODE_PATH_LICENSE, STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../common/constants';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { MonitoringTimeContainer } from './use_monitoring_time';
const CODE_PATHS = [CODE_PATH_LICENSE];
export const LicensePage: React.FC<{}> = () => {
const title = i18n.translate('xpack.monitoring.license.licenseRouteTitle', {
defaultMessage: 'License',
});
const { setIsDisabled } = useContext(MonitoringTimeContainer.Context);
useEffect(() => {
setIsDisabled(true);
return () => {
setIsDisabled(false);
};
}, [setIsDisabled]);
const state = useContext(GlobalStateContext);
const clusterUuid = state.cluster_uuid;
const ccs = state.ccs;
const [clusters, setClusters] = useState([] as any);
const { services } = useKibana<{ data: any }>();
const timezone = services.uiSettings?.get('dateFormat:tz');
const uploadLicensePath = services.application?.getUrlForApp('management', {
path: 'stack/license_management/upload_license',
});
const getPageData = useCallback(async () => {
const bounds = services.data?.query.timefilter.timefilter.getBounds();
let url = '../api/monitoring/v1/clusters';
if (clusterUuid) {
url += `/${clusterUuid}`;
}
try {
const response = await services.http?.fetch(url, {
method: 'POST',
body: JSON.stringify({
ccs,
timeRange: {
min: bounds.min.toISOString(),
max: bounds.max.toISOString(),
},
codePaths: CODE_PATHS,
}),
});
setClusters(formatClusters(response));
} catch (err) {
// TODO handle error
}
}, [ccs, clusterUuid, services.data?.query.timefilter.timefilter, services.http]);
return (
<PageTemplate title={title} pageTitle="" getPageData={getPageData}>
{licenseComponent(clusters, timezone, uploadLicensePath)}
</PageTemplate>
);
};
function licenseComponent(
clusters: any,
timezone: string,
uploadLicensePath: string | undefined
): any {
if (clusters.length) {
const cluster = clusters[0];
const isPrimaryCluster = cluster.isPrimary;
const license = cluster.license;
let expiryDate = license?.expiry_date_in_millis;
if (expiryDate !== undefined) {
expiryDate = formatDateTimeLocal(expiryDate, timezone);
}
const isExpired = Date.now() > expiryDate;
return (
<License
isPrimaryCluster={isPrimaryCluster}
status={license.status}
type={license.type}
isExpired={isExpired}
expiryDate={expiryDate}
uploadLicensePath={uploadLicensePath}
/>
);
} else {
return null;
}
}
// From x-pack/plugins/monitoring/common/formatting.ts with corrected typing
// TODO open github issue to correct other usages
export function formatDateTimeLocal(date: number | Date, timezone: string | null) {
return moment.tz(date, timezone || moment.tz.guess()).format('LL LTS');
}
function formatClusters(clusters: any) {
return clusters.map(formatCluster);
}
function formatCluster(cluster: any) {
if (cluster.cluster_uuid === STANDALONE_CLUSTER_CLUSTER_UUID) {
cluster.cluster_name = 'Standalone Cluster';
}
return cluster;
}

View file

@ -34,6 +34,7 @@ export const useMonitoringTime = () => {
const [refreshInterval, setRefreshInterval] = useState(value || DEFAULT_REFRESH_INTERVAL_VALUE);
const [isPaused, setIsPaused] = useState(pause || DEFAULT_REFRESH_INTERVAL_PAUSE);
const [currentTimerange, setTimeRange] = useState<TimeOptions>(defaultTimeRange);
const [isDisabled, setIsDisabled] = useState(false);
const handleTimeChange = useCallback(
(start: string, end: string) => {
@ -50,6 +51,8 @@ export const useMonitoringTime = () => {
refreshInterval,
setIsPaused,
isPaused,
setIsDisabled,
isDisabled,
};
};

View file

@ -6,3 +6,4 @@
*/
export const PageLoading: FunctionComponent<Props>;
export const License: FunctionComponent<Props>;

View file

@ -30,6 +30,7 @@ export const MonitoringToolbar: React.FC<MonitoringToolbarProps> = ({ pageTitle,
refreshInterval,
setIsPaused,
isPaused,
isDisabled,
} = useContext(MonitoringTimeContainer.Context);
const state = useContext(GlobalStateContext);
@ -85,6 +86,7 @@ export const MonitoringToolbar: React.FC<MonitoringToolbarProps> = ({ pageTitle,
<EuiFlexItem grow={false}>
<div style={{ padding: 8 }}>
<EuiSuperDatePicker
isDisabled={isDisabled}
start={currentTimerange.from}
end={currentTimerange.to}
onTimeChange={onTimeChange}