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