diff --git a/webapp/packages/core-blocks/src/Tabs/Tab/TabDefault.tsx b/webapp/packages/core-blocks/src/Tabs/Tab/TabDefault.tsx index ad64af080e..5c14f14135 100644 --- a/webapp/packages/core-blocks/src/Tabs/Tab/TabDefault.tsx +++ b/webapp/packages/core-blocks/src/Tabs/Tab/TabDefault.tsx @@ -23,6 +23,7 @@ interface Props> { component?: React.FC; className?: string; style?: DynamicStyle[] | DynamicStyle; + disabled?: boolean; onOpen?: (tabId: string) => void; onClose?: (tabId: string) => void; } @@ -34,6 +35,7 @@ export function TabDefault>({ component, className, style, + disabled, onOpen, onClose, ...rest @@ -48,6 +50,7 @@ export function TabDefault>({ className={className} {...(rest as unknown as T)} style={style} + disabled={disabled} onOpen={onOpen} onClose={onClose} /> @@ -55,7 +58,7 @@ export function TabDefault>({ } return styled(styles)( - + {icon && } {name && } diff --git a/webapp/packages/core-blocks/src/Tabs/TabList.tsx b/webapp/packages/core-blocks/src/Tabs/TabList.tsx index d508c5b10f..d29c07acb5 100644 --- a/webapp/packages/core-blocks/src/Tabs/TabList.tsx +++ b/webapp/packages/core-blocks/src/Tabs/TabList.tsx @@ -16,11 +16,13 @@ import { TabsContext } from './TabsContext'; type Props = React.PropsWithChildren> & { style?: DynamicStyle[] | DynamicStyle; + childrenFirst?: boolean; }; export const TabList: React.FC = function TabList({ style, children, + childrenFirst, ...props }) { const state = useContext(TabsContext); @@ -30,9 +32,11 @@ export const TabList: React.FC = function TabList({ } if (state.container) { + const displayed = state.container.getDisplayed(state.props); return ( - {state.container.tabInfoList.map(tabInfo => ( + {childrenFirst && children} + {displayed.map(tabInfo => ( = 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} ); } diff --git a/webapp/packages/core-blocks/src/Tabs/TabPanelList.tsx b/webapp/packages/core-blocks/src/Tabs/TabPanelList.tsx index 9e328845bf..df48d6d94f 100644 --- a/webapp/packages/core-blocks/src/Tabs/TabPanelList.tsx +++ b/webapp/packages/core-blocks/src/Tabs/TabPanelList.tsx @@ -39,9 +39,11 @@ export const TabPanelList: React.FC = function TabPanelList({ return ; } + const displayed = state.container.getDisplayed(state.props); + return styled(styles)( <> - {state.container.tabInfoList.map(tabInfo => ( + {displayed.map(tabInfo => ( , TOptions extends tab?: () => React.FC; 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, TOptions extends Record readonly tabInfoMap: Map>; @computed get tabInfoList(): Array> { - 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> { + return this.tabInfoList.filter(tabInfo => !tabInfo.isHidden?.(tabInfo.key, props)); + } + add(tabInfo: ITabInfoOptions): void { if (this.tabInfoMap.has(tabInfo.key)) { throw new Error('Tab with same key already exists'); diff --git a/webapp/packages/core-blocks/src/Tabs/TabsState.tsx b/webapp/packages/core-blocks/src/Tabs/TabsState.tsx index e874dde7c8..d4df6b9733 100644 --- a/webapp/packages/core-blocks/src/Tabs/TabsState.tsx +++ b/webapp/packages/core-blocks/src/Tabs/TabsState.tsx @@ -33,7 +33,7 @@ export function TabsState>({ onChange, ...rest }: Props): React.ReactElement | null { - if (!currentTabId && container && container.tabInfoList.length > 0) { + if (!selectedId && !currentTabId && container && container.tabInfoList.length > 0) { currentTabId = container.tabInfoList[0].key; } diff --git a/webapp/packages/core-bootstrap/src/manifest.ts b/webapp/packages/core-bootstrap/src/manifest.ts index 44851e2f8e..bc29112c78 100644 --- a/webapp/packages/core-bootstrap/src/manifest.ts +++ b/webapp/packages/core-bootstrap/src/manifest.ts @@ -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, diff --git a/webapp/packages/core-connections/src/index.ts b/webapp/packages/core-connections/src/index.ts index 4b1bdb1e62..04c317d21b 100644 --- a/webapp/packages/core-connections/src/index.ts +++ b/webapp/packages/core-connections/src/index.ts @@ -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';