feat: enhance project directory resolution and auto-refresh in MemberLogsTab
- Updated `TeamMemberLogsFinder` to improve project directory resolution by falling back to `leadSessionId` if the encoded directory does not exist, enhancing reliability in locating project logs. - Refactored `MemberLogsTab` to implement an initial loading state and auto-refresh functionality for ongoing tasks, improving user experience during log retrieval. - Adjusted error handling and loading indicators to provide clearer feedback based on task status.
This commit is contained in:
parent
c024f5bc78
commit
d60ac09925
2 changed files with 58 additions and 9 deletions
|
|
@ -257,9 +257,45 @@ export class TeamMemberLogsFinder {
|
|||
}
|
||||
|
||||
const normalizedProjectPath = trimTrailingSlashes(config.projectPath);
|
||||
const projectId = encodePath(normalizedProjectPath);
|
||||
const baseDir = extractBaseDir(projectId);
|
||||
const projectDir = path.join(getProjectsBasePath(), baseDir);
|
||||
let projectId = encodePath(normalizedProjectPath);
|
||||
let baseDir = extractBaseDir(projectId);
|
||||
let projectDir = path.join(getProjectsBasePath(), baseDir);
|
||||
|
||||
// If the encoded directory doesn't exist (symlink/cwd mismatch), fall back to locating
|
||||
// the project directory by leadSessionId which is unique and reliable.
|
||||
try {
|
||||
const stat = await fs.stat(projectDir);
|
||||
if (!stat.isDirectory()) {
|
||||
throw new Error('not a directory');
|
||||
}
|
||||
} catch {
|
||||
const leadSessionId =
|
||||
typeof config.leadSessionId === 'string' && config.leadSessionId.trim().length > 0
|
||||
? config.leadSessionId.trim()
|
||||
: null;
|
||||
if (leadSessionId) {
|
||||
const projectsBase = getProjectsBasePath();
|
||||
try {
|
||||
const entries = await fs.readdir(projectsBase, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
const candidateDir = path.join(projectsBase, entry.name);
|
||||
const leadPath = path.join(candidateDir, `${leadSessionId}.jsonl`);
|
||||
try {
|
||||
await fs.access(leadPath);
|
||||
projectDir = candidateDir;
|
||||
projectId = entry.name;
|
||||
baseDir = entry.name;
|
||||
break;
|
||||
} catch {
|
||||
// not this project
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const knownSessionIds = new Set<string>();
|
||||
if (config.leadSessionId) {
|
||||
|
|
|
|||
|
|
@ -41,15 +41,20 @@ export const MemberLogsTab = ({
|
|||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
let isInitial = true;
|
||||
const shouldAutoRefresh = taskId != null && taskStatus === 'in_progress';
|
||||
|
||||
void (async () => {
|
||||
const load = async (): Promise<void> => {
|
||||
try {
|
||||
if (taskId == null && !memberName) {
|
||||
if (!cancelled) setLogs([]);
|
||||
return;
|
||||
}
|
||||
if (isInitial) {
|
||||
setLoading(true);
|
||||
}
|
||||
setError(null);
|
||||
|
||||
const result =
|
||||
taskId != null
|
||||
? await api.teams.getLogsForTask(teamName, taskId, {
|
||||
|
|
@ -65,14 +70,20 @@ export const MemberLogsTab = ({
|
|||
setError(e instanceof Error ? e.message : 'Unknown error');
|
||||
}
|
||||
} finally {
|
||||
if (!cancelled) {
|
||||
if (!cancelled && isInitial) {
|
||||
setLoading(false);
|
||||
}
|
||||
isInitial = false;
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
void load();
|
||||
|
||||
const interval = shouldAutoRefresh ? setInterval(() => void load(), 5000) : null;
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
if (interval) clearInterval(interval);
|
||||
};
|
||||
}, [teamName, memberName, taskId, taskOwner, taskStatus]);
|
||||
|
||||
|
|
@ -133,7 +144,9 @@ export const MemberLogsTab = ({
|
|||
No logs found
|
||||
<p className="mt-1 text-[10px] opacity-60">
|
||||
{taskId != null
|
||||
? 'No session activity for this task yet'
|
||||
? taskStatus === 'in_progress'
|
||||
? 'Task is in progress — waiting for session activity (auto-refreshing)...'
|
||||
: 'No session activity for this task yet'
|
||||
: 'This member has no recorded session activity yet'}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue