Remove one unecessary query in node container

This commit is contained in:
Hakan Shehu
2024-10-05 11:15:35 +02:00
parent 217b0c2a69
commit 0ede4ece62
15 changed files with 92 additions and 121 deletions

View File

@@ -1,11 +1,10 @@
import React from 'react';
import { LocalNode } from '@/types/nodes';
import { Conversation } from '@/renderer/components/messages/conversation';
interface ChannelContainerNodeProps {
node: LocalNode;
nodeId: string;
}
export const ChannelContainerNode = ({ node }: ChannelContainerNodeProps) => {
return <Conversation conversationId={node.id} />;
export const ChannelContainerNode = ({ nodeId }: ChannelContainerNodeProps) => {
return <Conversation conversationId={nodeId} />;
};

View File

@@ -9,12 +9,12 @@ import { toast } from '@/renderer/components/ui/use-toast';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface NodeCollaboratorCreate {
id: string;
nodeId: string;
existingCollaborators: string[];
}
export const NodeCollaboratorCreate = ({
id,
nodeId,
existingCollaborators,
}: NodeCollaboratorCreate) => {
const workspace = useWorkspace();
@@ -47,7 +47,7 @@ export const NodeCollaboratorCreate = ({
mutate({
input: {
type: 'node_collaborator_create',
nodeId: id,
nodeId,
collaboratorIds: collaborators.map(
(collaborator) => collaborator.id,
),

View File

@@ -8,11 +8,11 @@ import { Icon } from '@/renderer/components/ui/icon';
import { NodeCollaborators } from '@/renderer/components/collaborators/node-collaborators';
interface NodeCollaboratorsPopoverProps {
id: string;
nodeId: string;
}
export const NodeCollaboratorsPopover = ({
id,
nodeId,
}: NodeCollaboratorsPopoverProps) => {
return (
<Popover>
@@ -23,7 +23,7 @@ export const NodeCollaboratorsPopover = ({
/>
</PopoverTrigger>
<PopoverContent className="mr-2 max-h-128 w-128 overflow-auto">
<NodeCollaborators id={id} />
<NodeCollaborators nodeId={nodeId} />
</PopoverContent>
</Popover>
);

View File

@@ -6,14 +6,14 @@ import { useQuery } from '@/renderer/hooks/use-query';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface NodeCollaboratorsProps {
id: string;
nodeId: string;
}
export const NodeCollaborators = ({ id }: NodeCollaboratorsProps) => {
export const NodeCollaborators = ({ nodeId }: NodeCollaboratorsProps) => {
const workspace = useWorkspace();
const { data, isPending } = useQuery({
type: 'node_collaborator_list',
nodeId: id,
nodeId,
userId: workspace.userId,
});
@@ -24,7 +24,7 @@ export const NodeCollaborators = ({ id }: NodeCollaboratorsProps) => {
return (
<div className="flex flex-col gap-2">
<NodeCollaboratorCreate
id={id}
nodeId={nodeId}
existingCollaborators={data.direct.map(
(collaborator) => collaborator.id,
)}
@@ -38,7 +38,7 @@ export const NodeCollaborators = ({ id }: NodeCollaboratorsProps) => {
{data.direct.map((collaborator) => (
<NodeCollaborator
key={collaborator.id}
nodeId={id}
nodeId={nodeId}
collaborator={collaborator}
removable={true}
/>
@@ -62,7 +62,7 @@ export const NodeCollaborators = ({ id }: NodeCollaboratorsProps) => {
{inheritGroup.collaborators?.map((collaborator) => (
<NodeCollaborator
key={collaborator.id}
nodeId={id}
nodeId={nodeId}
collaborator={collaborator}
/>
))}

View File

@@ -1,39 +1,34 @@
import React from 'react';
import { LocalNode } from '@/types/nodes';
import { useQuery } from '@/renderer/hooks/use-query';
import { Database } from '@/renderer/components/databases/database';
import { DatabaseViews } from '@/renderer/components/databases/database-views';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface DatabaseContainerNodeProps {
node: LocalNode;
nodeId: string;
}
export const DatabaseContainerNode = ({ node }: DatabaseContainerNodeProps) => {
export const DatabaseContainerNode = ({
nodeId,
}: DatabaseContainerNodeProps) => {
const workspace = useWorkspace();
const { data: database, isPending: isDatabasePending } = useQuery({
type: 'database_get',
databaseId: node.id,
userId: workspace.userId,
});
const { data: views, isPending: isViewsPending } = useQuery({
type: 'database_view_list',
databaseId: node.id,
databaseId: nodeId,
userId: workspace.userId,
});
if (isDatabasePending || isViewsPending) {
if (isViewsPending) {
return null;
}
if (!database) {
if (!views) {
return null;
}
return (
<Database node={database}>
<Database databaseId={nodeId}>
{views && <DatabaseViews views={views} />}
</Database>
);

View File

@@ -1,19 +1,35 @@
import React from 'react';
import { DatabaseContext } from '@/renderer/contexts/database';
import { DatabaseNode } from '@/types/databases';
import { useQuery } from '@/renderer/hooks/use-query';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface DatabaseProps {
node: DatabaseNode;
databaseId: string;
children: React.ReactNode;
}
export const Database = ({ node, children }: DatabaseProps) => {
export const Database = ({ databaseId, children }: DatabaseProps) => {
const workspace = useWorkspace();
const { data: database, isPending: isDatabasePending } = useQuery({
type: 'database_get',
databaseId,
userId: workspace.userId,
});
if (isDatabasePending) {
return null;
}
if (!database) {
return null;
}
return (
<DatabaseContext.Provider
value={{
id: node.id,
name: node.name,
fields: node.fields,
id: database.id,
name: database.name,
fields: database.fields,
}}
>
{children}

View File

@@ -54,15 +54,15 @@ import { useWorkspace } from '@/renderer/contexts/workspace';
import { EditorObserver } from '@/renderer/editor/observer';
interface DocumentEditorProps {
node: LocalNode;
nodeId: string;
nodes: Map<string, LocalNode>;
}
export const DocumentEditor = ({ node, nodes }: DocumentEditorProps) => {
export const DocumentEditor = ({ nodeId, nodes }: DocumentEditorProps) => {
const workspace = useWorkspace();
const observer = React.useMemo<EditorObserver>(
() => new EditorObserver(workspace, workspace as any, node, nodes),
[node.id],
() => new EditorObserver(workspace, workspace as any, nodeId, nodes),
[nodeId],
);
const editor = useEditor(
@@ -133,7 +133,7 @@ export const DocumentEditor = ({ node, nodes }: DocumentEditorProps) => {
}
},
},
[node.id],
[nodeId],
);
React.useEffect(() => {

View File

@@ -1,18 +1,17 @@
import React from 'react';
import { LocalNode } from '@/types/nodes';
import { DocumentEditor } from '@/renderer/components/documents/document-editor';
import { useQuery } from '@/renderer/hooks/use-query';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface DocumentProps {
node: LocalNode;
nodeId: string;
}
export const Document = ({ node }: DocumentProps) => {
export const Document = ({ nodeId }: DocumentProps) => {
const workspace = useWorkspace();
const { data, isPending } = useQuery({
type: 'document_get',
nodeId: node.id,
nodeId,
userId: workspace.userId,
});
@@ -20,5 +19,5 @@ export const Document = ({ node }: DocumentProps) => {
return null;
}
return <DocumentEditor key={node.id} node={node} nodes={data?.nodes} />;
return <DocumentEditor key={nodeId} nodeId={nodeId} nodes={data?.nodes} />;
};

View File

@@ -1,16 +1,15 @@
import React from 'react';
import { ScrollArea } from '@/renderer/components/ui/scroll-area';
import { LocalNode } from '@/types/nodes';
import { Document } from '@/renderer/components/documents/document';
interface PageContainerNodeProps {
node: LocalNode;
nodeId: string;
}
export const PageContainerNode = ({ node }: PageContainerNodeProps) => {
export const PageContainerNode = ({ nodeId }: PageContainerNodeProps) => {
return (
<ScrollArea className="h-full max-h-full w-full overflow-y-auto px-10 pb-12">
<Document node={node} />
<Document nodeId={nodeId} />
</ScrollArea>
);
};

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { useQuery } from '@/renderer/hooks/use-query';
import { LocalNode } from '@/types/nodes';
import { Database } from '@/renderer/components/databases/database';
import { RecordAttributes } from '@/renderer/components/records/record-attributes';
import { ScrollArea } from '@/renderer/components/ui/scroll-area';
@@ -9,25 +8,19 @@ import { Separator } from '@/renderer/components/ui/separator';
import { useWorkspace } from '@/renderer/contexts/workspace';
interface RecordContainerNodeProps {
node: LocalNode;
nodeId: string;
}
export const RecordContainerNode = ({ node }: RecordContainerNodeProps) => {
export const RecordContainerNode = ({ nodeId }: RecordContainerNodeProps) => {
const workspace = useWorkspace();
const { data: record, isPending: isRecordPending } = useQuery({
type: 'record_get',
recordId: node.id,
recordId: nodeId,
userId: workspace.userId,
});
const { data: database, isPending: isDatabasePending } = useQuery({
type: 'database_get',
databaseId: node.parentId,
userId: workspace.userId,
});
if (isRecordPending || isDatabasePending) {
if (isRecordPending) {
return null;
}
@@ -36,11 +29,11 @@ export const RecordContainerNode = ({ node }: RecordContainerNodeProps) => {
}
return (
<Database node={database}>
<Database databaseId={record.parentId}>
<ScrollArea className="h-full max-h-full w-full overflow-y-auto px-10 pb-12">
<RecordAttributes record={record} />
<Separator className="my-4 w-full" />
<Document node={node} />
<Document nodeId={nodeId} />
</ScrollArea>
</Database>
);

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { LocalNode } from '@/types/nodes';
import {
Breadcrumb as BreadcrumbWrapper,
BreadcrumbEllipsis,
@@ -25,14 +24,14 @@ import { BreadcrumbItemEditor } from '@/renderer/components/workspaces/container
import { useQuery } from '@/renderer/hooks/use-query';
interface BreadcrumbProps {
node: LocalNode;
nodeId: string;
}
export const Breadcrumb = ({ node }: BreadcrumbProps) => {
export const Breadcrumb = ({ nodeId }: BreadcrumbProps) => {
const workspace = useWorkspace();
const { data, isPending } = useQuery({
type: 'breadcrumb_list',
nodeId: node.id,
nodeId,
userId: workspace.userId,
});
@@ -59,7 +58,7 @@ export const Breadcrumb = ({ node }: BreadcrumbProps) => {
}
}}
>
{breadcrumbNode.id === node.id ? (
{breadcrumbNode.id === nodeId ? (
<Popover>
<PopoverTrigger>
<BreadcrumbItem node={breadcrumbNode} />

View File

@@ -1,17 +1,16 @@
import React from 'react';
import { LocalNode } from '@/types/nodes';
import { Breadcrumb } from '@/renderer/components/workspaces/containers/breadcrumb';
import { NodeCollaboratorsPopover } from '@/renderer/components/collaborators/node-collaborators-popover';
interface ContainerHeaderProps {
node: LocalNode;
nodeId: string;
}
export const ContainerHeader = ({ node }: ContainerHeaderProps) => {
export const ContainerHeader = ({ nodeId }: ContainerHeaderProps) => {
return (
<div className="mx-1 flex h-12 items-center justify-between p-2 pr-4 text-foreground/80">
<Breadcrumb node={node} />
<NodeCollaboratorsPopover id={node.id} />
<Breadcrumb nodeId={nodeId} />
<NodeCollaboratorsPopover nodeId={nodeId} />
</div>
);
};

View File

@@ -1,41 +1,30 @@
import React from 'react';
import { match } from 'ts-pattern';
import { useParams } from 'react-router-dom';
import { NodeTypes } from '@/lib/constants';
import { PageContainerNode } from '@/renderer/components/pages/page-container-node';
import { ChannelContainerNode } from '@/renderer/components/channels/channel-container-node';
import { ContainerHeader } from '@/renderer/components/workspaces/containers/container-header';
import { Spinner } from '@/renderer/components/ui/spinner';
import { DatabaseContainerNode } from '@/renderer/components/databases/database-container-node';
import { useQuery } from '@/renderer/hooks/use-query';
import { RecordContainerNode } from '@/renderer/components/records/record-container-node';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { getIdType, IdType } from '@/lib/id';
export const Container = () => {
const workspace = useWorkspace();
const { nodeId } = useParams<{ nodeId: string }>();
const { data, isPending } = useQuery({
type: 'node_get',
nodeId: nodeId,
userId: workspace.userId,
});
if (isPending) {
return <Spinner />;
}
if (!data) {
if (!nodeId) {
return null;
}
const idType = getIdType(nodeId);
return (
<div className="flex h-full w-full flex-col">
<ContainerHeader node={data} />
{match(data.type)
.with(NodeTypes.Channel, () => <ChannelContainerNode node={data} />)
.with(NodeTypes.Page, () => <PageContainerNode node={data} />)
.with(NodeTypes.Database, () => <DatabaseContainerNode node={data} />)
.with(NodeTypes.Record, () => <RecordContainerNode node={data} />)
<ContainerHeader nodeId={nodeId} />
{match(idType)
.with(IdType.Channel, () => <ChannelContainerNode nodeId={nodeId} />)
.with(IdType.Page, () => <PageContainerNode nodeId={nodeId} />)
.with(IdType.Database, () => <DatabaseContainerNode nodeId={nodeId} />)
.with(IdType.Record, () => <RecordContainerNode nodeId={nodeId} />)
.otherwise(() => null)}
</div>
);

View File

@@ -1,41 +1,24 @@
import React from 'react';
import { Spinner } from '@/renderer/components/ui/spinner';
import { useQuery } from '@/renderer/hooks/use-query';
import { match } from 'ts-pattern';
import { NodeTypes } from '@/lib/constants';
import { ChannelContainerNode } from '@/renderer/components/channels/channel-container-node';
import { PageContainerNode } from '@/renderer/components/pages/page-container-node';
import { DatabaseContainerNode } from '@/renderer/components/databases/database-container-node';
import { RecordContainerNode } from '@/renderer/components/records/record-container-node';
import { useWorkspace } from '@/renderer/contexts/workspace';
import { getIdType, IdType } from '@/lib/id';
interface ModalContentProps {
nodeId: string;
}
export const ModalContent = ({ nodeId }: ModalContentProps) => {
const workspace = useWorkspace();
const { data, isPending } = useQuery({
type: 'node_get',
nodeId: nodeId,
userId: workspace.userId,
});
if (isPending) {
return <Spinner />;
}
if (!data) {
return null;
}
const idType = getIdType(nodeId);
return (
<div className="flex h-full w-full flex-col">
{match(data.type)
.with(NodeTypes.Channel, () => <ChannelContainerNode node={data} />)
.with(NodeTypes.Page, () => <PageContainerNode node={data} />)
.with(NodeTypes.Database, () => <DatabaseContainerNode node={data} />)
.with(NodeTypes.Record, () => <RecordContainerNode node={data} />)
{match(idType)
.with(IdType.Channel, () => <ChannelContainerNode nodeId={nodeId} />)
.with(IdType.Page, () => <PageContainerNode nodeId={nodeId} />)
.with(IdType.Database, () => <DatabaseContainerNode nodeId={nodeId} />)
.with(IdType.Record, () => <RecordContainerNode nodeId={nodeId} />)
.otherwise(() => null)}
</div>
);

View File

@@ -16,7 +16,7 @@ import { fromUint8Array, toUint8Array } from 'js-base64';
export class EditorObserver {
private readonly workspace: Workspace;
private readonly database: Kysely<WorkspaceDatabaseSchema>;
private readonly rootNode: LocalNode;
private readonly rootNodeId: string;
private readonly nodesMap: Map<string, LocalNode>;
private editorContent: JSONContent;
@@ -29,12 +29,12 @@ export class EditorObserver {
constructor(
workspace: Workspace,
database: Kysely<WorkspaceDatabaseSchema>,
rootNode: LocalNode,
rootNodeId: string,
nodesMap: Map<string, LocalNode>,
) {
this.workspace = workspace;
this.database = database;
this.rootNode = rootNode;
this.rootNodeId = rootNodeId;
this.nodesMap = nodesMap;
this.editorContent = this.buildEditorContent();
this.onEditorUpdateDebounced = debounce(
@@ -59,7 +59,7 @@ export class EditorObserver {
private buildEditorContent(): JSONContent {
const nodesArray = Array.from(this.nodesMap.values());
const contents = mapNodesToContents(this.rootNode.id, nodesArray);
const contents = mapNodesToContents(this.rootNodeId, nodesArray);
if (!contents.length) {
contents.push({
@@ -76,7 +76,7 @@ export class EditorObserver {
private async checkEditorContentChanges() {
const editorNodes = mapContentsToEditorNodes(
this.editorContent.content,
this.rootNode.id,
this.rootNodeId,
this.nodesMap,
);