mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Connection Details] Move tabs into the header (#183484)
## Summary
Closes https://github.com/elastic/kibana/issues/182966
*Connection Details* flyout tabs are now in the header of the flyout.
See the before/after below:
<img width="762" alt="image"
src="640378ad
-3d96-4fd5-8353-883a1609b55c">
This saves screen real-estate for more content in the flyout body.
### Checklist
Delete any items that are not applicable to this PR.
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [x] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
520f19d0a2
commit
668f0966fe
5 changed files with 85 additions and 52 deletions
|
@ -7,61 +7,21 @@
|
|||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import { EuiSpacer, EuiTab, EuiTabs } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useConnectionDetailsOpts } from './context';
|
||||
import { useConnectionDetailsService } from './context';
|
||||
import { EndpointsTab } from './tabs/endpoints_tab';
|
||||
import { ApiKeysTab } from './tabs/api_keys_tab';
|
||||
import { useBehaviorSubject } from './hooks/use_behavior_subject';
|
||||
|
||||
export const ConnectionDetails: React.FC = () => {
|
||||
type TabID = 'endpoints' | 'apiKeys';
|
||||
type Tab = [id: TabID, name: string, content: React.ReactNode];
|
||||
const service = useConnectionDetailsService();
|
||||
const tab = useBehaviorSubject(service.tabId$);
|
||||
|
||||
const ctx = useConnectionDetailsOpts();
|
||||
const [tab, setTab] = React.useState<TabID>('endpoints');
|
||||
|
||||
const tabs: Tab[] = [];
|
||||
|
||||
if (ctx.endpoints) {
|
||||
tabs.push([
|
||||
'endpoints',
|
||||
i18n.translate('cloud.connectionDetails.tab.endpoints', {
|
||||
defaultMessage: 'Endpoints',
|
||||
}),
|
||||
<EndpointsTab />,
|
||||
]);
|
||||
switch (tab) {
|
||||
case 'endpoints':
|
||||
return <EndpointsTab />;
|
||||
case 'apiKeys':
|
||||
return <ApiKeysTab />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ctx.apiKeys) {
|
||||
tabs.push([
|
||||
'apiKeys',
|
||||
i18n.translate('cloud.connectionDetails.tab.apiKeys', {
|
||||
defaultMessage: 'API key',
|
||||
}),
|
||||
<ApiKeysTab />,
|
||||
]);
|
||||
}
|
||||
|
||||
if (tabs.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiTabs>
|
||||
{tabs.map(([id, name]) => (
|
||||
<EuiTab
|
||||
key={id}
|
||||
onClick={() => setTab(id)}
|
||||
isSelected={tab === id}
|
||||
data-test-subj={`connectionDetailsTabBtn-${id}`}
|
||||
>
|
||||
{name}
|
||||
</EuiTab>
|
||||
))}
|
||||
</EuiTabs>
|
||||
<EuiSpacer />
|
||||
{tabs.find(([id]) => id === tab)?.[2] || null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { ConnectionDetails } from './connection_details';
|
||||
import { useConnectionDetailsOpts } from './context';
|
||||
import { Tabs } from './tabs';
|
||||
|
||||
export const ConnectionDetailsFlyoutContent: React.FC = () => {
|
||||
const ctx = useConnectionDetailsOpts();
|
||||
|
@ -46,6 +47,10 @@ export const ConnectionDetailsFlyoutContent: React.FC = () => {
|
|||
)}
|
||||
</p>
|
||||
</EuiText>
|
||||
{/* The -25px is as per EUI example: https://eui.elastic.co/#/layout/flyout */}
|
||||
<div style={{ marginBottom: '-25px' }}>
|
||||
<Tabs />
|
||||
</div>
|
||||
</EuiFlyoutHeader>
|
||||
);
|
||||
|
||||
|
|
|
@ -10,9 +10,10 @@ import { BehaviorSubject } from 'rxjs';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { ApiKey } from './tabs/api_keys_tab/views/success_form/types';
|
||||
import type { Format } from './tabs/api_keys_tab/views/success_form/format_select';
|
||||
import type { ConnectionDetailsOpts } from './types';
|
||||
import type { ConnectionDetailsOpts, TabID } from './types';
|
||||
|
||||
export class ConnectionDetailsService {
|
||||
public readonly tabId$ = new BehaviorSubject<TabID>('endpoints');
|
||||
public readonly showCloudId$ = new BehaviorSubject<boolean>(false);
|
||||
public readonly apiKeyName$ = new BehaviorSubject<string>('');
|
||||
public readonly apiKeyStatus$ = new BehaviorSubject<'configuring' | 'creating'>('configuring');
|
||||
|
@ -33,6 +34,10 @@ export class ConnectionDetailsService {
|
|||
});
|
||||
}
|
||||
|
||||
public readonly setTab = (tab: TabID) => {
|
||||
this.tabId$.next(tab);
|
||||
};
|
||||
|
||||
public readonly toggleShowCloudId = () => {
|
||||
this.showCloudId$.next(!this.showCloudId$.getValue());
|
||||
};
|
||||
|
|
61
packages/cloud/connection_details/tabs.tsx
Normal file
61
packages/cloud/connection_details/tabs.tsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import { EuiTab, EuiTabs } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useConnectionDetailsOpts, useConnectionDetailsService } from './context';
|
||||
import { useBehaviorSubject } from './hooks/use_behavior_subject';
|
||||
import { TabID } from './types';
|
||||
|
||||
export const Tabs: React.FC = () => {
|
||||
type Tab = [id: TabID, name: string];
|
||||
|
||||
const ctx = useConnectionDetailsOpts();
|
||||
const service = useConnectionDetailsService();
|
||||
const tab = useBehaviorSubject(service.tabId$);
|
||||
|
||||
const tabs: Tab[] = [];
|
||||
|
||||
if (ctx.endpoints) {
|
||||
tabs.push([
|
||||
'endpoints',
|
||||
i18n.translate('cloud.connectionDetails.tab.endpoints', {
|
||||
defaultMessage: 'Endpoints',
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
if (ctx.apiKeys) {
|
||||
tabs.push([
|
||||
'apiKeys',
|
||||
i18n.translate('cloud.connectionDetails.tab.apiKeys', {
|
||||
defaultMessage: 'API key',
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
if (tabs.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiTabs>
|
||||
{tabs.map(([id, name]) => (
|
||||
<EuiTab
|
||||
key={id}
|
||||
onClick={() => service.setTab(id)}
|
||||
isSelected={tab === id}
|
||||
data-test-subj={`connectionDetailsTabBtn-${id}`}
|
||||
>
|
||||
{name}
|
||||
</EuiTab>
|
||||
))}
|
||||
</EuiTabs>
|
||||
);
|
||||
};
|
|
@ -31,3 +31,5 @@ export interface ConnectionDetailsOptsApiKeys {
|
|||
}>;
|
||||
hasPermission: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
export type TabID = 'endpoints' | 'apiKeys';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue