mirror of
https://github.com/colanode/colanode.git
synced 2025-12-29 00:25:03 +01:00
Remove one unecessary query in node container
This commit is contained in:
@@ -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} />;
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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} />;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user