mirror of
https://github.com/grafana/grafana.git
synced 2025-07-28 21:42:27 +08:00
136 lines
4.4 KiB
TypeScript
136 lines
4.4 KiB
TypeScript
import getDefaultMonacoLanguages from 'lib/monaco-languages';
|
|
import { useState } from 'react';
|
|
import { useAsync } from 'react-use';
|
|
import SwaggerUI from 'swagger-ui-react';
|
|
|
|
import { createTheme, monacoLanguageRegistry, SelectableValue } from '@grafana/data';
|
|
import { Trans } from '@grafana/i18n';
|
|
import { Stack, Select, UserIcon, UserView, Button } from '@grafana/ui';
|
|
import { setMonacoEnv } from 'app/core/monacoEnv';
|
|
import { ThemeProvider } from 'app/core/utils/ConfigProvider';
|
|
import grafanaIconSvg from 'img/grafana_icon.svg';
|
|
|
|
import { NamespaceContext, WrappedPlugins } from './plugins';
|
|
|
|
export const Page = () => {
|
|
const theme = createTheme({ colors: { mode: 'light' } });
|
|
const [url, setURL] = useState<SelectableValue<string>>();
|
|
const urls = useAsync(async () => {
|
|
const v2 = { label: 'Grafana API (OpenAPI v2)', key: 'openapi2', value: 'public/api-merged.json' };
|
|
const v3 = { label: 'Grafana API (OpenAPI v3)', key: 'openapi3', value: 'public/openapi3.json' };
|
|
const urls: Array<SelectableValue<string>> = [v2, v3];
|
|
|
|
const rsp = await fetch('openapi/v3');
|
|
const apis = await rsp.json();
|
|
for (const [key, val] of Object.entries<any>(apis.paths)) {
|
|
const parts = key.split('/');
|
|
if (parts.length === 3) {
|
|
urls.push({
|
|
key: `${parts[1]}-${parts[2]}`,
|
|
label: `${parts[1]}/${parts[2]}`,
|
|
value: val.serverRelativeURL.substring(1), // remove initial slash
|
|
});
|
|
}
|
|
}
|
|
|
|
let idx = 0;
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const api = urlParams.get('api');
|
|
if (api) {
|
|
urls.forEach((url, i) => {
|
|
if (url.key === api) {
|
|
idx = i;
|
|
}
|
|
});
|
|
}
|
|
|
|
monacoLanguageRegistry.setInit(getDefaultMonacoLanguages);
|
|
setMonacoEnv();
|
|
|
|
setURL(urls[idx]); // Remove to start at the generic landing page
|
|
return urls;
|
|
});
|
|
|
|
const [userView, setUserView] = useState<UserView>();
|
|
|
|
const namespace = useAsync(async () => {
|
|
const response = await fetch('api/frontend/settings');
|
|
if (!response.ok) {
|
|
console.warn('No settings found');
|
|
return 'default';
|
|
}
|
|
const val = await response.json();
|
|
return val.namespace;
|
|
});
|
|
|
|
useAsync(async () => {
|
|
const response = await fetch('api/user');
|
|
if (!response.ok) {
|
|
console.warn('No user found, show login button');
|
|
return;
|
|
}
|
|
const val = await response.json();
|
|
setUserView({
|
|
user: {
|
|
name: val.email || val.login,
|
|
avatarUrl: val.avatarUrl,
|
|
},
|
|
lastActiveAt: new Date(),
|
|
});
|
|
});
|
|
|
|
return (
|
|
<div>
|
|
<ThemeProvider value={theme}>
|
|
<NamespaceContext.Provider value={namespace.value}>
|
|
<div style={{ backgroundColor: '#000', padding: '10px' }}>
|
|
<Stack justifyContent={'space-between'}>
|
|
<img height="40" src={grafanaIconSvg} alt="Grafana" />
|
|
<Select
|
|
options={urls.value}
|
|
isClearable={false /* TODO -- when we allow a landing page, this can be true */}
|
|
onChange={(v) => {
|
|
const url = new URL(window.location.href);
|
|
url.hash = '';
|
|
if (v?.key) {
|
|
url.searchParams.set('api', v.key);
|
|
} else {
|
|
url.searchParams.delete('api');
|
|
}
|
|
window.history.pushState(null, '', url);
|
|
setURL(v);
|
|
}}
|
|
value={url}
|
|
isLoading={urls.loading}
|
|
/>
|
|
<div style={{ marginTop: '5px' }}>
|
|
{userView ? (
|
|
<UserIcon userView={userView} />
|
|
) : (
|
|
<a href="/login">
|
|
<Button variant="primary">
|
|
<Trans i18nKey="swagger.login">Login</Trans>
|
|
</Button>
|
|
</a>
|
|
)}
|
|
</div>
|
|
</Stack>
|
|
</div>
|
|
|
|
{url?.value && (
|
|
<SwaggerUI
|
|
url={url.value}
|
|
presets={[WrappedPlugins]}
|
|
deepLinking={true}
|
|
tryItOutEnabled={true}
|
|
queryConfigEnabled={false}
|
|
persistAuthorization={false}
|
|
/>
|
|
)}
|
|
{!url?.value && <div>...{/** TODO, we can make an api docs loading page here */}</div>}
|
|
</NamespaceContext.Provider>
|
|
</ThemeProvider>
|
|
</div>
|
|
);
|
|
};
|