fix: multi owner
This commit is contained in:
@@ -178,9 +178,12 @@ export function ScriptExplorer({
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{memberScriptGroups.map((group) => (
|
||||
{memberScriptGroups.map((group) => {
|
||||
const ownerKey = group.user?.user_id ?? "anon";
|
||||
return (
|
||||
<WorkspaceTreeGroup
|
||||
key={group.user?.user_id ?? "anon"}
|
||||
key={ownerKey}
|
||||
groupKey={`__group__${ownerKey}`}
|
||||
title={`${group.user?.display_name}`}
|
||||
scripts={group.scripts}
|
||||
directories={group.directories}
|
||||
@@ -196,7 +199,8 @@ export function ScriptExplorer({
|
||||
onToggle={onToggle}
|
||||
loadingChildrenPaths={loadingChildrenPaths}
|
||||
/>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
{filteredScripts.length === 0 && (
|
||||
<div className="tree-empty">
|
||||
<span className="tree-empty__icon">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type MouseEvent as ReactMouseEvent } from "react";
|
||||
import { type MouseEvent as ReactMouseEvent, useEffect } from "react";
|
||||
|
||||
import Icon from "../../components/common/Icon";
|
||||
import type {
|
||||
@@ -23,12 +23,14 @@ type WorkspaceTreeProps = {
|
||||
target: WorkspaceTreeTarget,
|
||||
) => void;
|
||||
readOnly?: boolean;
|
||||
// 唯一标识此 group(通常 `__group__<owner_user_id>`),让多个 owner 的 group 各自独立展开。
|
||||
groupKey: string;
|
||||
expandedPaths: Set<string>;
|
||||
onToggle: (path: string) => void;
|
||||
loadingChildrenPaths: Set<string>;
|
||||
};
|
||||
|
||||
type WorkspaceTreeItemsProps = Omit<WorkspaceTreeProps, "title" | "readOnly"> & {
|
||||
type WorkspaceTreeItemsProps = Omit<WorkspaceTreeProps, "title" | "readOnly" | "groupKey"> & {
|
||||
path: string;
|
||||
depth: number;
|
||||
};
|
||||
@@ -65,19 +67,27 @@ export function WorkspaceTreeGroup({
|
||||
onSelect,
|
||||
onContextMenu,
|
||||
readOnly = false,
|
||||
groupKey,
|
||||
expandedPaths,
|
||||
onToggle,
|
||||
loadingChildrenPaths,
|
||||
}: WorkspaceTreeProps) {
|
||||
const open = expandedPaths.has("");
|
||||
const childrenLoading = loadingChildrenPaths.has("");
|
||||
const open = expandedPaths.has(groupKey);
|
||||
// 首次挂载自动展开(保留原本 useState(true) 的默认展开行为)。
|
||||
// toggleExpanded 内识别 `__group__` 前缀,不会触发 loadChildren。
|
||||
useEffect(() => {
|
||||
if (!expandedPaths.has(groupKey)) {
|
||||
void onToggle(groupKey);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [groupKey]);
|
||||
return (
|
||||
<div className="tree-group">
|
||||
<button
|
||||
className={`tree-group__title${open ? " is-open" : ""}`}
|
||||
type="button"
|
||||
aria-expanded={open}
|
||||
onClick={() => onToggle("")}
|
||||
onClick={() => onToggle(groupKey)}
|
||||
onContextMenu={onContextMenu
|
||||
? (event) => onContextMenu(event, { kind: "root", path: "" })
|
||||
: undefined}
|
||||
@@ -86,7 +96,6 @@ export function WorkspaceTreeGroup({
|
||||
<Icon name="folder" size={17} />
|
||||
<span>{title}</span>
|
||||
<em>{scripts.length}</em>
|
||||
{childrenLoading && <span className="loading-spinner" />}
|
||||
</button>
|
||||
{open && (
|
||||
<div className="tree-group__items">
|
||||
|
||||
@@ -293,7 +293,8 @@ export const useScriptWorkspaceStore = create<State>((set, get) => {
|
||||
next.delete(path);
|
||||
} else {
|
||||
next.add(path);
|
||||
if (!state.loadedChildPaths.has(path)) {
|
||||
// group key (`__group__<owner_id>`) 不是 workspace 路径,不调 loadChildren
|
||||
if (!path.startsWith("__group__") && !state.loadedChildPaths.has(path)) {
|
||||
void get().loadChildren(path);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user