refactor(tree): borrow cleanups from the sibling expand-all impl
- extract collectAllIds / collectBranchIds into tree/utils and use them in
space-tree.tsx instead of inline closures
- drop the duplicate SidebarPageTreeDto, reuse the existing SidebarPageDto
for the /pages/tree endpoint
- type the getSpaceTree client call as api.post<{ items: IPage[] }>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -96,7 +96,7 @@ export async function getSpaceTree(params: {
|
|||||||
spaceId: string;
|
spaceId: string;
|
||||||
pageId?: string;
|
pageId?: string;
|
||||||
}): Promise<IPage[]> {
|
}): Promise<IPage[]> {
|
||||||
const req = await api.post("/pages/tree", params);
|
const req = await api.post<{ items: IPage[] }>("/pages/tree", params);
|
||||||
return req.data.items;
|
return req.data.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import {
|
|||||||
buildTree,
|
buildTree,
|
||||||
buildTreeWithChildren,
|
buildTreeWithChildren,
|
||||||
mergeRootTrees,
|
mergeRootTrees,
|
||||||
|
collectAllIds,
|
||||||
|
collectBranchIds,
|
||||||
} from "@/features/page/tree/utils/utils.ts";
|
} from "@/features/page/tree/utils/utils.ts";
|
||||||
import { SpaceTreeNode } from "@/features/page/tree/types.ts";
|
import { SpaceTreeNode } from "@/features/page/tree/types.ts";
|
||||||
import { treeModel } from "@/features/page/tree/model/tree-model";
|
import { treeModel } from "@/features/page/tree/model/tree-model";
|
||||||
@@ -226,16 +228,7 @@ const SpaceTree = forwardRef<SpaceTreeApi, SpaceTreeProps>(function SpaceTree(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Open every branch node (node with children) of the current space only.
|
// Open every branch node (node with children) of the current space only.
|
||||||
const branchIds: string[] = [];
|
const branchIds = collectBranchIds(fullTree);
|
||||||
const collectBranchIds = (nodes: SpaceTreeNode[]) => {
|
|
||||||
for (const n of nodes) {
|
|
||||||
if (n.children && n.children.length > 0) {
|
|
||||||
branchIds.push(n.id);
|
|
||||||
collectBranchIds(n.children);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
collectBranchIds(fullTree);
|
|
||||||
|
|
||||||
setOpenTreeNodes((prev) => {
|
setOpenTreeNodes((prev) => {
|
||||||
const next = { ...prev };
|
const next = { ...prev };
|
||||||
@@ -260,14 +253,7 @@ const SpaceTree = forwardRef<SpaceTreeApi, SpaceTreeProps>(function SpaceTree(
|
|||||||
const collapseAll = useCallback(() => {
|
const collapseAll = useCallback(() => {
|
||||||
// The open-map is shared across spaces; collapse only current-space ids so
|
// The open-map is shared across spaces; collapse only current-space ids so
|
||||||
// other spaces' expanded state is left intact.
|
// other spaces' expanded state is left intact.
|
||||||
const ids = new Set<string>();
|
const ids = collectAllIds(filteredData);
|
||||||
const walk = (nodes: SpaceTreeNode[]) => {
|
|
||||||
for (const n of nodes) {
|
|
||||||
ids.add(n.id);
|
|
||||||
if (n.children?.length) walk(n.children);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
walk(filteredData);
|
|
||||||
|
|
||||||
setOpenTreeNodes((prev) => {
|
setOpenTreeNodes((prev) => {
|
||||||
const next = { ...prev };
|
const next = { ...prev };
|
||||||
|
|||||||
@@ -216,3 +216,33 @@ export function mergeRootTrees(
|
|||||||
|
|
||||||
return sortPositionKeys(merged);
|
return sortPositionKeys(merged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Collect every node id in the tree (roots, branches, leaves). Used by
|
||||||
|
// collapseAll to clear the open-state map for all current-space nodes.
|
||||||
|
export function collectAllIds(nodes: SpaceTreeNode[]): string[] {
|
||||||
|
const ids: string[] = [];
|
||||||
|
const walk = (list: SpaceTreeNode[]) => {
|
||||||
|
for (const n of list) {
|
||||||
|
ids.push(n.id);
|
||||||
|
if (n.children?.length) walk(n.children);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
walk(nodes);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect ids of branch nodes (nodes that have children). Used by expandAll to
|
||||||
|
// open every branch in the open-state map; leaves need no entry.
|
||||||
|
export function collectBranchIds(nodes: SpaceTreeNode[]): string[] {
|
||||||
|
const ids: string[] = [];
|
||||||
|
const walk = (list: SpaceTreeNode[]) => {
|
||||||
|
for (const n of list) {
|
||||||
|
if (n.children?.length) {
|
||||||
|
ids.push(n.id);
|
||||||
|
walk(n.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
walk(nodes);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,13 +9,3 @@ export class SidebarPageDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
pageId: string;
|
pageId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SidebarPageTreeDto {
|
|
||||||
@IsOptional()
|
|
||||||
@IsUUID()
|
|
||||||
spaceId?: string;
|
|
||||||
|
|
||||||
@IsOptional()
|
|
||||||
@IsString()
|
|
||||||
pageId?: string;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
|
||||||
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
|
import { PaginationOptions } from '@docmost/db/pagination/pagination-options';
|
||||||
import { Page, User, Workspace } from '@docmost/db/types/entity.types';
|
import { Page, User, Workspace } from '@docmost/db/types/entity.types';
|
||||||
import { SidebarPageDto, SidebarPageTreeDto } from './dto/sidebar-page.dto';
|
import { SidebarPageDto } from './dto/sidebar-page.dto';
|
||||||
import {
|
import {
|
||||||
SpaceCaslAction,
|
SpaceCaslAction,
|
||||||
SpaceCaslSubject,
|
SpaceCaslSubject,
|
||||||
@@ -581,7 +581,7 @@ export class PageController {
|
|||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@Post('/tree')
|
@Post('/tree')
|
||||||
async getPagesTree(
|
async getPagesTree(
|
||||||
@Body() dto: SidebarPageTreeDto,
|
@Body() dto: SidebarPageDto,
|
||||||
@AuthUser() user: User,
|
@AuthUser() user: User,
|
||||||
) {
|
) {
|
||||||
if (!dto.spaceId && !dto.pageId) {
|
if (!dto.spaceId && !dto.pageId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user