mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core-blocks): CB-341 Tab Container's disabled & hidden states
This commit is contained in:
@@ -23,6 +23,7 @@ interface Props<T = Record<string, any>> {
|
||||
component?: React.FC<TabProps & T>;
|
||||
className?: string;
|
||||
style?: DynamicStyle[] | DynamicStyle;
|
||||
disabled?: boolean;
|
||||
onOpen?: (tabId: string) => void;
|
||||
onClose?: (tabId: string) => void;
|
||||
}
|
||||
@@ -34,6 +35,7 @@ export function TabDefault<T = Record<string, any>>({
|
||||
component,
|
||||
className,
|
||||
style,
|
||||
disabled,
|
||||
onOpen,
|
||||
onClose,
|
||||
...rest
|
||||
@@ -48,6 +50,7 @@ export function TabDefault<T = Record<string, any>>({
|
||||
className={className}
|
||||
{...(rest as unknown as T)}
|
||||
style={style}
|
||||
disabled={disabled}
|
||||
onOpen={onOpen}
|
||||
onClose={onClose}
|
||||
/>
|
||||
@@ -55,7 +58,7 @@ export function TabDefault<T = Record<string, any>>({
|
||||
}
|
||||
|
||||
return styled(styles)(
|
||||
<Tab tabId={tabId} className={className} style={style} onOpen={onOpen} onClose={onClose}>
|
||||
<Tab tabId={tabId} className={className} style={style} disabled={disabled} onOpen={onOpen} onClose={onClose}>
|
||||
{icon && <TabIcon icon={icon} />}
|
||||
{name && <TabTitle><Translate token={name} /></TabTitle>}
|
||||
</Tab>
|
||||
|
||||
@@ -16,11 +16,13 @@ import { TabsContext } from './TabsContext';
|
||||
|
||||
type Props = React.PropsWithChildren<Omit<TabListOptions, keyof TabStateReturn>> & {
|
||||
style?: DynamicStyle[] | DynamicStyle;
|
||||
childrenFirst?: boolean;
|
||||
};
|
||||
|
||||
export const TabList: React.FC<Props> = function TabList({
|
||||
style,
|
||||
children,
|
||||
childrenFirst,
|
||||
...props
|
||||
}) {
|
||||
const state = useContext(TabsContext);
|
||||
@@ -30,9 +32,11 @@ export const TabList: React.FC<Props> = function TabList({
|
||||
}
|
||||
|
||||
if (state.container) {
|
||||
const displayed = state.container.getDisplayed(state.props);
|
||||
return (
|
||||
<BaseTabList {...props} {...state.state}>
|
||||
{state.container.tabInfoList.map(tabInfo => (
|
||||
{childrenFirst && children}
|
||||
{displayed.map(tabInfo => (
|
||||
<TabDefault
|
||||
key={tabInfo.key}
|
||||
tabId={tabInfo.key}
|
||||
@@ -41,11 +45,12 @@ export const TabList: React.FC<Props> = function TabList({
|
||||
component={tabInfo.tab?.()}
|
||||
{...state.props}
|
||||
style={style}
|
||||
disabled={tabInfo.isDisabled?.(tabInfo.key, state.props)}
|
||||
onOpen={tabInfo.onOpen}
|
||||
onClose={tabInfo.onClose}
|
||||
/>
|
||||
))}
|
||||
{children}
|
||||
{!childrenFirst && children}
|
||||
</BaseTabList>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,9 +39,11 @@ export const TabPanelList: React.FC<Props> = function TabPanelList({
|
||||
return <Panel tabId={tabInfo.key} {...state?.props} />;
|
||||
}
|
||||
|
||||
const displayed = state.container.getDisplayed(state.props);
|
||||
|
||||
return styled(styles)(
|
||||
<>
|
||||
{state.container.tabInfoList.map(tabInfo => (
|
||||
{displayed.map(tabInfo => (
|
||||
<TabPanel
|
||||
key={tabInfo.key}
|
||||
tabId={tabInfo.key}
|
||||
|
||||
@@ -20,6 +20,9 @@ export interface ITabInfoOptions<TProps = Record<string, any>, TOptions extends
|
||||
tab?: () => React.FC<TabProps & TProps>;
|
||||
panel: () => React.FC<{ tabId: string } & TProps>;
|
||||
|
||||
isHidden?: (tabId: string, props?: TProps) => boolean;
|
||||
isDisabled?: (tabId: string, props?: TProps) => boolean;
|
||||
|
||||
onClose?: (tabId: string) => void;
|
||||
onOpen?: (tabId: string) => void;
|
||||
}
|
||||
@@ -36,13 +39,18 @@ export class TabsContainer<TProps = Record<string, any>, TOptions extends Record
|
||||
readonly tabInfoMap: Map<string, ITabInfo<TProps, TOptions>>;
|
||||
|
||||
@computed get tabInfoList(): Array<ITabInfo<TProps, TOptions>> {
|
||||
return Array.from(this.tabInfoMap.values()).sort((a, b) => a.order - b.order);
|
||||
return Array.from(this.tabInfoMap.values())
|
||||
.sort((a, b) => a.order - b.order);
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.tabInfoMap = new Map();
|
||||
}
|
||||
|
||||
getDisplayed(props?: TProps): Array<ITabInfo<TProps, TOptions>> {
|
||||
return this.tabInfoList.filter(tabInfo => !tabInfo.isHidden?.(tabInfo.key, props));
|
||||
}
|
||||
|
||||
add(tabInfo: ITabInfoOptions<TProps, TOptions>): void {
|
||||
if (this.tabInfoMap.has(tabInfo.key)) {
|
||||
throw new Error('Tab with same key already exists');
|
||||
|
||||
@@ -33,7 +33,7 @@ export function TabsState<T = Record<string, any>>({
|
||||
onChange,
|
||||
...rest
|
||||
}: Props<T>): React.ReactElement | null {
|
||||
if (!currentTabId && container && container.tabInfoList.length > 0) {
|
||||
if (!selectedId && !currentTabId && container && container.tabInfoList.length > 0) {
|
||||
currentTabId = container.tabInfoList[0].key;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@ import {
|
||||
CreateConnectionService,
|
||||
ConnectionManualService,
|
||||
ConnectionSearchService,
|
||||
CreateConnectionBaseBootstrap
|
||||
CreateConnectionBaseBootstrap,
|
||||
ConnectionFormService
|
||||
} from '@cloudbeaver/core-connections';
|
||||
import { PluginManifest } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, ContextMenuService } from '@cloudbeaver/core-dialogs';
|
||||
@@ -124,6 +125,7 @@ export const coreManifest: PluginManifest = {
|
||||
SessionExpireService,
|
||||
SessionExpiredDialogService,
|
||||
ConnectionsLocaleService,
|
||||
ConnectionFormService,
|
||||
ConnectionDialogsService,
|
||||
ConnectionSchemaManagerService,
|
||||
ConnectionInfoResource,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './Administration/Connections/ConnectionForm/ConnectionFormService';
|
||||
export * from './Administration/Connections/ConnectionsAdministration';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationNavService';
|
||||
export * from './Administration/Connections/ConnectionsAdministrationService';
|
||||
|
||||
Reference in New Issue
Block a user