mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
refactor: CB-1239 nav node info resources
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { runInAction } from 'mobx';
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import {
|
||||
GraphQLService, CachedMapResource, ResourceKey, isResourceKeyList
|
||||
@@ -55,22 +57,18 @@ export class DBObjectResource extends CachedMapResource<string, DBObject> {
|
||||
navNodeId: parentId,
|
||||
});
|
||||
|
||||
for (const dbObject of dbObjects) {
|
||||
this.set(
|
||||
dbObject.id,
|
||||
{
|
||||
navNodeId: dbObject.id,
|
||||
...dbObject.object,
|
||||
}
|
||||
);
|
||||
}
|
||||
runInAction(() => {
|
||||
for (const dbObject of dbObjects) {
|
||||
this.set(dbObject.id, dbObject);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async loadDBObjectInfo(navNodeId: string): Promise<DBObject> {
|
||||
const { objectInfo: { object } } = await this.graphQLService.sdk.getDBObjectInfo({
|
||||
const { objectInfo } = await this.graphQLService.sdk.getDBObjectInfo({
|
||||
navNodeId,
|
||||
});
|
||||
|
||||
return { navNodeId, ...object };
|
||||
return objectInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { DatabaseObjectInfo, NavigatorNodeInfo } from '@cloudbeaver/core-sdk';
|
||||
import type { NavigatorNodeInfo, NavNodeDbObjectInfoFragment } from '@cloudbeaver/core-sdk';
|
||||
|
||||
export type NavNodeInfo = NavigatorNodeInfo;
|
||||
|
||||
@@ -15,6 +15,4 @@ export type NavNode = Omit<NavNodeInfo, 'object'> & {
|
||||
objectFeatures: string[];
|
||||
};
|
||||
|
||||
export type DBObject = DatabaseObjectInfo & {
|
||||
navNodeId: string;
|
||||
};
|
||||
export type DBObject = NavNodeDbObjectInfoFragment;
|
||||
|
||||
@@ -59,10 +59,13 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
) {
|
||||
super();
|
||||
|
||||
makeObservable<NavTreeResource, 'setNavObject' | 'connectionRemoveHandler'>(this, {
|
||||
makeObservable<this, 'setNavObject' | 'connectionRemoveHandler'>(this, {
|
||||
childrenLimit: computed,
|
||||
setDetails: action,
|
||||
setNavObject: action,
|
||||
deleteInNode: action,
|
||||
unshiftToNode: action,
|
||||
pushToNode: action,
|
||||
connectionRemoveHandler: action.bound,
|
||||
});
|
||||
|
||||
@@ -119,13 +122,19 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
const parents: string[] = [];
|
||||
const deletedIds: string[][] = [];
|
||||
|
||||
for (const path of nodePaths) {
|
||||
const node = this.navNodeInfoResource.get(path);
|
||||
|
||||
if (node) {
|
||||
this.deleteInNode(node.parentId, [path]);
|
||||
parents.push(node.parentId);
|
||||
deletedIds.push([path]);
|
||||
}
|
||||
}
|
||||
|
||||
this.deleteInNode(resourceKeyList(parents), deletedIds);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,16 +152,20 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
deleteInNode(key: string, value: string[]): void;
|
||||
deleteInNode(key: ResourceKeyList<string>, value: string[][]): void;
|
||||
deleteInNode(keyObject: ResourceKey<string>, valueObject: string[] | string[][]): void {
|
||||
const deletedKeys: string[] = [];
|
||||
|
||||
ResourceKeyUtils.forEach(keyObject, (key, i) => {
|
||||
const values = i === -1 ? (valueObject as string[]) : (valueObject as string[][])[i];
|
||||
const currentValue = this.data.get(key);
|
||||
|
||||
if (currentValue) {
|
||||
this.data.set(key, currentValue.filter(value => !values.includes(value)));
|
||||
this.delete(resourceKeyList(values));
|
||||
}
|
||||
|
||||
deletedKeys.push(...values);
|
||||
});
|
||||
|
||||
this.delete(resourceKeyList(deletedKeys));
|
||||
this.markUpdated(keyObject);
|
||||
this.onItemAdd.execute(keyObject);
|
||||
}
|
||||
@@ -190,13 +203,15 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
set(key: string, value: string[]): void;
|
||||
set(key: ResourceKeyList<string>, value: string[][]): void;
|
||||
set(keyObject: ResourceKey<string>, valueObject: string[] | string[][]): void {
|
||||
const childrenToRemove: string[] = [];
|
||||
ResourceKeyUtils.forEach(keyObject, (key, i) => {
|
||||
const value = i === -1 ? (valueObject as string[]) : (valueObject as string[][])[i];
|
||||
const childrenToRemove = this.data.get(key) || [];
|
||||
const children = this.data.get(key) || [];
|
||||
childrenToRemove.push(...children.filter(navNodeId => !value.includes(navNodeId)));
|
||||
this.data.set(key, value);
|
||||
this.delete(resourceKeyList(childrenToRemove.filter(navNodeId => !value.includes(navNodeId))));
|
||||
});
|
||||
|
||||
this.delete(resourceKeyList(childrenToRemove));
|
||||
this.markUpdated(keyObject);
|
||||
this.onItemAdd.execute(keyObject);
|
||||
}
|
||||
@@ -206,6 +221,7 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
delete(key: ResourceKey<string>): void;
|
||||
delete(key: ResourceKey<string>): void {
|
||||
const items = this.getNestedChildren(key);
|
||||
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -215,9 +231,9 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
}
|
||||
|
||||
const allKeys = resourceKeyList(items);
|
||||
this.navNodeInfoResource.delete(allKeys);
|
||||
this.markUpdated(allKeys);
|
||||
this.onItemDelete.execute(allKeys);
|
||||
this.navNodeInfoResource.delete(allKeys);
|
||||
}
|
||||
|
||||
protected async loader(key: ResourceKey<string>): Promise<Map<string, string[]>> {
|
||||
@@ -237,11 +253,13 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
getNestedChildren(navNode: ResourceKey<string>): string[] {
|
||||
const nestedChildren: string[] = [];
|
||||
let prevChildren: string[];
|
||||
|
||||
if (isResourceKeyList(navNode)) {
|
||||
prevChildren = navNode.list.concat();
|
||||
} else {
|
||||
prevChildren = [navNode, ...(this.get(navNode) || [])];
|
||||
}
|
||||
|
||||
nestedChildren.push(...prevChildren);
|
||||
|
||||
while (prevChildren.length) {
|
||||
@@ -257,6 +275,8 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
private async connectionUpdateHandler(key: ResourceKey<string>) {
|
||||
await this.markOutdated(ROOT_NODE_PATH);
|
||||
|
||||
const closedConnectionsTree: string[] = [];
|
||||
|
||||
await ResourceKeyUtils.forEachAsync(key, async key => {
|
||||
const nodeId = NodeManagerUtils.connectionIdToConnectionNodeId(key);
|
||||
|
||||
@@ -264,7 +284,7 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
const connectionInfo = this.connectionInfo.get(key);
|
||||
|
||||
if (!connectionInfo?.connected) {
|
||||
this.delete(resourceKeyList(this.get(nodeId) || []));
|
||||
closedConnectionsTree.push(...this.get(nodeId) || []);
|
||||
} else {
|
||||
await this.markTreeOutdated(nodeId);
|
||||
}
|
||||
@@ -272,10 +292,14 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
|
||||
const node = this.navNodeInfoResource.get(nodeId);
|
||||
|
||||
if (node) {
|
||||
if (node && node.parentId !== ROOT_NODE_PATH) {
|
||||
await this.markOutdated(node.parentId);
|
||||
}
|
||||
});
|
||||
|
||||
if (closedConnectionsTree.length > 0) {
|
||||
this.delete(resourceKeyList(closedConnectionsTree));
|
||||
}
|
||||
}
|
||||
|
||||
private connectionRemoveHandler(key: ResourceKey<string>) {
|
||||
@@ -303,23 +327,24 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
for (const node of data) {
|
||||
const metadata = this.metadata.get(node.parentPath);
|
||||
|
||||
this.setDetails(node.navNodeInfo.id, metadata.withDetails);
|
||||
this.setDetails(resourceKeyList(node.navNodeChildren.map(node => node.id)), metadata.withDetails);
|
||||
this.setDetails(resourceKeyList([
|
||||
node.navNodeInfo.id,
|
||||
...node.navNodeChildren.map(node => node.id),
|
||||
]), metadata.withDetails);
|
||||
}
|
||||
|
||||
this.navNodeInfoResource.set(
|
||||
resourceKeyList(data.map(data => data.parentPath)),
|
||||
data.map(data => this.navNodeInfoResource.navNodeInfoToNavNode(data.navNodeInfo)).flat()
|
||||
);
|
||||
|
||||
this.navNodeInfoResource.set(
|
||||
resourceKeyList(data.map(data => data.navNodeChildren.map(node => node.id)).flat()),
|
||||
data.map(
|
||||
data => data.navNodeChildren.map(
|
||||
node => this.navNodeInfoResource.navNodeInfoToNavNode(node, data.parentPath)
|
||||
)
|
||||
).flat()
|
||||
);
|
||||
resourceKeyList([
|
||||
...data.map(data => data.parentPath),
|
||||
...data.map(data => data.navNodeChildren.map(node => node.id)).flat(),
|
||||
]), [
|
||||
...data.map(data => this.navNodeInfoResource.navNodeInfoToNavNode(data.navNodeInfo)).flat(),
|
||||
...data.map(
|
||||
data => data.navNodeChildren.map(
|
||||
node => this.navNodeInfoResource.navNodeInfoToNavNode(node, data.parentPath)
|
||||
)
|
||||
).flat(),
|
||||
]);
|
||||
|
||||
this.set(
|
||||
resourceKeyList(data.map(data => data.parentPath)),
|
||||
@@ -328,17 +353,19 @@ export class NavTreeResource extends CachedMapResource<string, string[]> {
|
||||
} else {
|
||||
const metadata = this.metadata.get(data.parentPath);
|
||||
|
||||
this.setDetails(data.navNodeInfo.id, metadata.withDetails);
|
||||
this.setDetails(resourceKeyList(data.navNodeChildren.map(node => node.id)), metadata.withDetails);
|
||||
this.setDetails(resourceKeyList([
|
||||
data.navNodeInfo.id,
|
||||
...data.navNodeChildren.map(node => node.id),
|
||||
]), metadata.withDetails);
|
||||
|
||||
this.navNodeInfoResource.set(
|
||||
data.parentPath,
|
||||
this.navNodeInfoResource.navNodeInfoToNavNode(data.navNodeInfo)
|
||||
);
|
||||
|
||||
this.navNodeInfoResource.set(
|
||||
resourceKeyList(data.navNodeChildren.map(node => node.id)),
|
||||
data.navNodeChildren.map(node => this.navNodeInfoResource.navNodeInfoToNavNode(node, data.parentPath))
|
||||
resourceKeyList([
|
||||
data.parentPath,
|
||||
...data.navNodeChildren.map(node => node.id),
|
||||
]), [
|
||||
this.navNodeInfoResource.navNodeInfoToNavNode(data.navNodeInfo),
|
||||
...data.navNodeChildren.map(node => this.navNodeInfoResource.navNodeInfoToNavNode(node, data.parentPath)),
|
||||
]
|
||||
);
|
||||
|
||||
this.set(data.parentPath, data.navNodeChildren.map(node => node.id));
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fragment NavNodeDBObjectInfo on NavigatorNodeInfo {
|
||||
id
|
||||
object {
|
||||
type
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,6 @@ query getChildrenDBObjectInfo(
|
||||
$filter: ObjectPropertyFilter
|
||||
) {
|
||||
dbObjects: navNodeChildren(parentPath: $navNodeId) {
|
||||
id
|
||||
object {
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
...NavNodeDBObjectInfo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
query getDBObjectInfo($navNodeId: ID!, $filter: ObjectPropertyFilter) {
|
||||
objectInfo: navNodeInfo(nodePath: $navNodeId) {
|
||||
object {
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
...NavNodeDBObjectInfo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1570,6 +1570,8 @@ export interface DatabaseConnectionFragment { id: string; name: string; descript
|
||||
|
||||
export interface DatabaseDriverFragment { id: string; name?: Maybe<string>; icon?: Maybe<string>; description?: Maybe<string>; defaultPort?: Maybe<string>; defaultDatabase?: Maybe<string>; defaultServer?: Maybe<string>; defaultUser?: Maybe<string>; sampleURL?: Maybe<string>; embedded?: Maybe<boolean>; anonymousAccess?: Maybe<boolean>; promotedScore?: Maybe<number>; defaultAuthModel: string; applicableNetworkHandlers: Array<Maybe<string>>; driverParameters?: Maybe<any>; providerProperties?: Maybe<Array<{ id?: Maybe<string>; displayName?: Maybe<string>; description?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; defaultValue?: Maybe<any>; validValues?: Maybe<Array<Maybe<any>>>; length: ObjectPropertyLength; features: string[]; order: number }>>; driverProperties?: Maybe<Array<{ id?: Maybe<string>; displayName?: Maybe<string>; description?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; defaultValue?: Maybe<any>; validValues?: Maybe<Array<Maybe<any>>> }>> }
|
||||
|
||||
export interface NavNodeDbObjectInfoFragment { id: string; object?: Maybe<{ type?: Maybe<string>; features?: Maybe<string[]>; properties?: Maybe<Array<Maybe<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>>> }> }
|
||||
|
||||
export interface NavNodeInfoFragment { id: string; name?: Maybe<string>; hasChildren?: Maybe<boolean>; nodeType?: Maybe<string>; icon?: Maybe<string>; folder?: Maybe<boolean>; inline?: Maybe<boolean>; navigable?: Maybe<boolean>; features?: Maybe<string[]>; object?: Maybe<{ features?: Maybe<string[]> }>; nodeDetails?: Maybe<Array<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>> }
|
||||
|
||||
export interface NavNodePropertiesFragment { id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }
|
||||
@@ -1667,14 +1669,14 @@ export type GetChildrenDbObjectInfoQueryVariables = Exact<{
|
||||
filter?: Maybe<ObjectPropertyFilter>;
|
||||
}>;
|
||||
|
||||
export interface GetChildrenDbObjectInfoQuery { dbObjects: Array<{ id: string; object?: Maybe<{ features?: Maybe<string[]>; properties?: Maybe<Array<Maybe<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>>> }> }> }
|
||||
export interface GetChildrenDbObjectInfoQuery { dbObjects: Array<{ id: string; object?: Maybe<{ type?: Maybe<string>; features?: Maybe<string[]>; properties?: Maybe<Array<Maybe<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>>> }> }> }
|
||||
|
||||
export type GetDbObjectInfoQueryVariables = Exact<{
|
||||
navNodeId: Scalars['ID'];
|
||||
filter?: Maybe<ObjectPropertyFilter>;
|
||||
}>;
|
||||
|
||||
export interface GetDbObjectInfoQuery { objectInfo: { object?: Maybe<{ features?: Maybe<string[]>; properties?: Maybe<Array<Maybe<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>>> }> } }
|
||||
export interface GetDbObjectInfoQuery { objectInfo: { id: string; object?: Maybe<{ type?: Maybe<string>; features?: Maybe<string[]>; properties?: Maybe<Array<Maybe<{ id?: Maybe<string>; category?: Maybe<string>; dataType?: Maybe<string>; description?: Maybe<string>; displayName?: Maybe<string>; length: ObjectPropertyLength; features: string[]; value?: Maybe<any>; order: number }>>> }> } }
|
||||
|
||||
export type NavDeleteNodesMutationVariables = Exact<{
|
||||
nodePaths: Array<Scalars['ID']> | Scalars['ID'];
|
||||
@@ -1966,6 +1968,18 @@ export const NavNodePropertiesFragmentDoc = `
|
||||
order
|
||||
}
|
||||
`;
|
||||
export const NavNodeDbObjectInfoFragmentDoc = `
|
||||
fragment NavNodeDBObjectInfo on NavigatorNodeInfo {
|
||||
id
|
||||
object {
|
||||
type
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
}
|
||||
${NavNodePropertiesFragmentDoc}`;
|
||||
export const NavNodeInfoFragmentDoc = `
|
||||
fragment NavNodeInfo on NavigatorNodeInfo {
|
||||
id
|
||||
@@ -2775,28 +2789,17 @@ export const MetadataGetNodeDdlDocument = `
|
||||
export const GetChildrenDbObjectInfoDocument = `
|
||||
query getChildrenDBObjectInfo($navNodeId: ID!, $filter: ObjectPropertyFilter) {
|
||||
dbObjects: navNodeChildren(parentPath: $navNodeId) {
|
||||
id
|
||||
object {
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
...NavNodeDBObjectInfo
|
||||
}
|
||||
}
|
||||
${NavNodePropertiesFragmentDoc}`;
|
||||
${NavNodeDbObjectInfoFragmentDoc}`;
|
||||
export const GetDbObjectInfoDocument = `
|
||||
query getDBObjectInfo($navNodeId: ID!, $filter: ObjectPropertyFilter) {
|
||||
objectInfo: navNodeInfo(nodePath: $navNodeId) {
|
||||
object {
|
||||
features
|
||||
properties(filter: $filter) {
|
||||
...NavNodeProperties
|
||||
}
|
||||
}
|
||||
...NavNodeDBObjectInfo
|
||||
}
|
||||
}
|
||||
${NavNodePropertiesFragmentDoc}`;
|
||||
${NavNodeDbObjectInfoFragmentDoc}`;
|
||||
export const NavDeleteNodesDocument = `
|
||||
mutation navDeleteNodes($nodePaths: [ID!]!) {
|
||||
navDeleteNodes(nodePaths: $nodePaths)
|
||||
|
||||
+4
-2
@@ -28,8 +28,10 @@ export const ObjectProperties = observer<Props>(function ObjectProperties({
|
||||
const translate = useTranslate();
|
||||
const dbObject = useMapResource(DBObjectResource, objectId);
|
||||
const styles = useStyles(BASE_CONTAINERS_STYLES);
|
||||
const { categories, isUncategorizedExists } = useObjectPropertyCategories(dbObject.data?.properties ?? emptyArray);
|
||||
const properties = dbObject.data?.properties;
|
||||
const { categories, isUncategorizedExists } = useObjectPropertyCategories(
|
||||
dbObject.data?.object?.properties ?? emptyArray
|
||||
);
|
||||
const properties = dbObject.data?.object?.properties;
|
||||
|
||||
return styled(styles)(
|
||||
<Loader state={dbObject}>{() => styled(styles)(
|
||||
|
||||
+18
-12
@@ -6,11 +6,13 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { DBObjectResource, NavNodeInfoResource, NavNodeTransformViewComponent, NavTreeResource } from '@cloudbeaver/core-app';
|
||||
import { Loader, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { DBObject, DBObjectResource, NavNodeInfoResource, NavNodeTransformViewComponent, NavTreeResource } from '@cloudbeaver/core-app';
|
||||
import { Loader, TextPlaceholder, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { resourceKeyList } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import { ObjectChildrenPropertyTable } from '../../ObjectPropertyTable/ObjectChildrenPropertyTable';
|
||||
@@ -24,33 +26,37 @@ const style = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const VirtualFolderPanel: NavNodeTransformViewComponent = function VirtualFolderPanel({
|
||||
export const VirtualFolderPanel: NavNodeTransformViewComponent = observer(function VirtualFolderPanel({
|
||||
folderId,
|
||||
nodeId,
|
||||
}) {
|
||||
const translate = useTranslate();
|
||||
const nodeType = VirtualFolderUtils.getNodeType(folderId);
|
||||
const navNodeInfoResource = useService(NavNodeInfoResource);
|
||||
const tree = useMapResource(NavTreeResource, nodeId);
|
||||
const key = resourceKeyList([nodeId, ...tree.data || []]);
|
||||
const key = resourceKeyList(tree.data || []);
|
||||
const dbObject = useMapResource(DBObjectResource, key, {
|
||||
async onLoad(resource: DBObjectResource) {
|
||||
await resource.loadChildren(nodeId, key);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
const nodeIds = navNodeInfoResource
|
||||
.get(resourceKeyList(tree.data || []))
|
||||
.filter(node => node?.nodeType === nodeType)
|
||||
.map(node => node!.id);
|
||||
const objects = dbObject.data
|
||||
.filter(object => object && navNodeInfoResource.get(object.id)?.nodeType === nodeType) as DBObject[];
|
||||
|
||||
return styled(style)(
|
||||
<Loader state={[tree, dbObject]}>{() => styled(style)(
|
||||
<>
|
||||
<tab-wrapper>
|
||||
<ObjectChildrenPropertyTable nodeIds={nodeIds} />
|
||||
</tab-wrapper>
|
||||
{objects.length === 0 ? (
|
||||
<TextPlaceholder>{translate('plugin_object_viewer_table_no_items')}</TextPlaceholder>
|
||||
) : (
|
||||
<tab-wrapper>
|
||||
<ObjectChildrenPropertyTable objects={objects} />
|
||||
</tab-wrapper>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Loader>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
+6
-7
@@ -10,7 +10,7 @@ import { observer } from 'mobx-react-lite';
|
||||
import { useState } from 'react';
|
||||
import styled, { css, use } from 'reshadow';
|
||||
|
||||
import { NavNode, NavNodeContextMenuService, NavNodeManagerService, useDatabaseObjectInfo, useNode } from '@cloudbeaver/core-app';
|
||||
import { DBObject, NavNode, NavNodeContextMenuService, NavNodeManagerService, useNode } from '@cloudbeaver/core-app';
|
||||
import {
|
||||
StaticImage, TableItem, TableColumnValue, TableItemSelect, useMouse, getComputed, Icon, useStateDelay
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
@@ -69,17 +69,16 @@ const itemStyles = css`
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
objectId: string;
|
||||
dbObject: DBObject;
|
||||
columns: number;
|
||||
}
|
||||
|
||||
export const Item = observer<Props>(function Item({
|
||||
objectId, columns,
|
||||
dbObject, columns,
|
||||
}) {
|
||||
const styles = useStyles(itemStyles);
|
||||
|
||||
const objectId = dbObject.id;
|
||||
const { node } = useNode(objectId);
|
||||
const { dbObject } = useDatabaseObjectInfo(objectId);
|
||||
|
||||
if (!node) {
|
||||
return styled(styles)(
|
||||
@@ -97,7 +96,7 @@ export const Item = observer<Props>(function Item({
|
||||
);
|
||||
}
|
||||
|
||||
if (!dbObject?.properties || dbObject.properties.length === 0) {
|
||||
if (!dbObject.object?.properties || dbObject.object.properties.length === 0) {
|
||||
return styled(styles)(
|
||||
<TableItem item={objectId}>
|
||||
<TableColumnValue centerContent>
|
||||
@@ -123,7 +122,7 @@ export const Item = observer<Props>(function Item({
|
||||
<StaticImage icon={node.icon} />
|
||||
</icon>
|
||||
</TableColumnValue>
|
||||
{dbObject.properties.map((property, index) => (
|
||||
{dbObject.object.properties.map((property, index) => (
|
||||
<ItemName key={property.id} node={node} property={property} index={index} />
|
||||
))}
|
||||
</TableItem>
|
||||
|
||||
+24
-14
@@ -9,8 +9,8 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { useDatabaseObjectInfo } from '@cloudbeaver/core-app';
|
||||
import { TableHeader, TableBody, Table, useTable } from '@cloudbeaver/core-blocks';
|
||||
import type { DBObject } from '@cloudbeaver/core-app';
|
||||
import { TableHeader, TableBody, Table, useTable, getComputed } from '@cloudbeaver/core-blocks';
|
||||
import { composes, useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { Header } from './Header';
|
||||
@@ -50,31 +50,41 @@ const style = composes(
|
||||
);
|
||||
|
||||
interface Props {
|
||||
nodeIds: string[];
|
||||
objects: DBObject[];
|
||||
}
|
||||
|
||||
export const ObjectChildrenPropertyTable = observer<Props>(function ObjectPropertyTable({
|
||||
nodeIds,
|
||||
objects,
|
||||
}) {
|
||||
const firstChild = nodeIds[0] || '';
|
||||
const dbObject = useDatabaseObjectInfo(firstChild).dbObject;
|
||||
const properties = dbObject?.properties;
|
||||
|
||||
const styles = useStyles(style);
|
||||
const table = useTable();
|
||||
|
||||
return styled(useStyles(style))(
|
||||
if (objects.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const baseObject = getComputed(() => (
|
||||
objects
|
||||
.slice()
|
||||
.sort((a, b) => (a.object?.properties?.length || 0) - (b.object?.properties?.length || 0))
|
||||
));
|
||||
|
||||
const nodeIds = getComputed(() => objects.map(object => object.id));
|
||||
const properties = baseObject[0].object?.properties || [];
|
||||
|
||||
return styled(styles)(
|
||||
<wrapper>
|
||||
<table-container>
|
||||
<Table selectedItems={table.selected}>
|
||||
<TableHeader>
|
||||
<Header properties={properties || []} />
|
||||
<Header properties={properties} />
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{nodeIds.map(id => (
|
||||
{objects.map(object => (
|
||||
<Item
|
||||
key={id}
|
||||
objectId={id}
|
||||
columns={properties?.length || 0}
|
||||
key={object.id}
|
||||
dbObject={object}
|
||||
columns={properties.length}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
+6
-7
@@ -9,7 +9,7 @@
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { DBObjectResource, NavTreeResource } from '@cloudbeaver/core-app';
|
||||
import { DBObject, DBObjectResource, NavTreeResource } from '@cloudbeaver/core-app';
|
||||
import { Loader, TextPlaceholder, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { resourceKeyList } from '@cloudbeaver/core-sdk';
|
||||
@@ -38,13 +38,16 @@ export const ObjectPropertyTable = observer<ObjectPropertyTableProps>(function O
|
||||
}) {
|
||||
const translate = useTranslate();
|
||||
const tree = useMapResource(NavTreeResource, objectId);
|
||||
const key = resourceKeyList([objectId, ...tree.data || []]);
|
||||
const key = resourceKeyList(tree.data || []);
|
||||
const dbObject = useMapResource(DBObjectResource, key, {
|
||||
async onLoad(resource: DBObjectResource) {
|
||||
await resource.loadChildren(objectId, key);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
|
||||
const objects = dbObject.data as DBObject[];
|
||||
|
||||
return styled(styles)(
|
||||
<Loader state={[tree, dbObject]} style={styles}>{() => styled(styles)(
|
||||
<>
|
||||
@@ -52,7 +55,7 @@ export const ObjectPropertyTable = observer<ObjectPropertyTableProps>(function O
|
||||
<TextPlaceholder>{translate('plugin_object_viewer_table_no_items')}</TextPlaceholder>
|
||||
) : (
|
||||
<div>
|
||||
<ObjectChildrenPropertyTable nodeIds={tree.data} />
|
||||
<ObjectChildrenPropertyTable objects={objects} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
@@ -60,7 +63,3 @@ export const ObjectPropertyTable = observer<ObjectPropertyTableProps>(function O
|
||||
</Loader>
|
||||
);
|
||||
});
|
||||
|
||||
export const objectPropertyTablePanel = (parentId: string, objectId: string) => (
|
||||
<ObjectPropertyTable parentId={parentId} objectId={objectId} />
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user