sync: update from private repo (c764df2f)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-06-29 01:32:25 +00:00
parent b857c33ef6
commit a6d1879d63
75 changed files with 3874 additions and 334 deletions
+26 -8
View File
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useSpaces, useArchiveSpace } from '../../hooks/useSpaces';
@@ -425,21 +425,39 @@ function SpaceChat({
const qc = useQueryClient();
const auth = useAuthState();
const { data: allTasks } = useLocalTaskList();
const { data: spaces } = useSpaces();
const [showCreate, setShowCreate] = useState(false);
const { search: searchQuery, status: selectedStatus, sort: sortMode, scope } = filter;
const setScope = (val: TaskScope) => onFilterChange({ scope: val });
const setSearchQuery = (val: string) => onFilterChange({ search: val });
const setSelectedStatus = (val: 'all' | StatusColumn) => onFilterChange({ status: val });
const setSortMode = (val: SortMode) => onFilterChange({ sort: val });
const spaceTasks = filterTasksForSpace(allTasks ?? [], spaceId, isPersonalSpace);
// 自分/他メンバーの切替。共有ワークスペースで「他の人のタスク」が存在するときだけ
// 出す(個人ワークスペースや単独利用では意味がないので隠す)。スコープ分割は Tasks
// ページと同じ filterTasksByScope を再利用する(owner_id null は others 側、という
// 既存規約に合わせる)。フィルタ状態は URL に永続化されるため、スペース切替時は App の
// onSelectSpace が search/status/sort/scope を明示リセットする(remount 依存ではない)。
const userId = auth.mode === 'authenticated' ? auth.user.id : null;
const hasOthersTasks = userId != null && spaceTasks.some(t => t.ownerId !== userId);
// 認証無効 (no-auth 単独利用) は admin 同等に扱う(App.tsx の isAdmin と同じ規約)。
const isAdmin = auth.mode === 'authenticated' ? auth.user.role === 'admin' : true;
// case スペースの id 集合。個人バケツ判定(null か case でない id = 誰かの個人
// スペース)に使う。admin の listSpaces は全 case スペースを返すので集合は完全。
const caseSpaceIds = useMemo(
() => new Set((spaces ?? []).filter(s => s.kind === 'case').map(s => s.id)),
[spaces],
);
let spaceTasks = filterTasksForSpace(allTasks ?? [], spaceId, isPersonalSpace, caseSpaceIds);
// 可視性ルール: 個人ワークスペースは本人専用。admin だけが他ユーザーの個人コンテンツを
// 「他のメンバー」タブで監視できる。非 admin の個人スペースは自分の所有分に絞り、他人を
// 一切出さない(リスト API が public/org 等を返しても個人 WS には混ぜない)。
if (isPersonalSpace && !isAdmin && userId != null) {
spaceTasks = spaceTasks.filter(t => t.ownerId === userId);
}
// 自分/他メンバーの切替。共有ワークスペースのメンバー間、または個人スペースを admin が
// 監視するときに「他の人のタスク」が存在する場合だけ出す。スコープ分割は Tasks ページと
// 同じ filterTasksByScope を再利用する(owner_id null は others 側、という既存規約に合わ
// せる)。フィルタ状態は URL に永続化されるため、スペース切替時は App の onSelectSpace が
// search/status/sort/scope を明示リセットする(remount 依存ではない)。
const othersAllowed = !isPersonalSpace || isAdmin;
const hasOthersTasks = othersAllowed && userId != null && spaceTasks.some(t => t.ownerId !== userId);
const tasks = userId != null && hasOthersTasks
? filterTasksByScope(spaceTasks, scope, userId)
: spaceTasks;