perf(renderer): ignore lead activity churn in task sidebar
This commit is contained in:
parent
e21e80ac05
commit
c9e9e4ae09
1 changed files with 63 additions and 28 deletions
|
|
@ -59,7 +59,7 @@ import {
|
||||||
} from './taskFiltersState';
|
} from './taskFiltersState';
|
||||||
|
|
||||||
import type { TaskFiltersState } from './taskFiltersState';
|
import type { TaskFiltersState } from './taskFiltersState';
|
||||||
import type { GlobalTask, TeamSummary } from '@shared/types';
|
import type { GlobalTask, LeadActivityState, TeamSummary } from '@shared/types';
|
||||||
|
|
||||||
const TASK_GROUPING_STORAGE_KEY = 'sidebarTasksGrouping';
|
const TASK_GROUPING_STORAGE_KEY = 'sidebarTasksGrouping';
|
||||||
|
|
||||||
|
|
@ -216,33 +216,65 @@ let cachedSidebarTeamsDerived: SidebarTeamsDerived = {
|
||||||
statusSummaries: [],
|
statusSummaries: [],
|
||||||
memberColorByTeam: new Map(),
|
memberColorByTeam: new Map(),
|
||||||
};
|
};
|
||||||
|
let cachedLeadOfflineTeamsSignature = '';
|
||||||
|
let cachedLeadOfflineTeamNames: string[] = [];
|
||||||
|
|
||||||
function encodeSignatureParts(parts: readonly unknown[]): string {
|
function appendSignaturePart(signature: string, part: unknown): string {
|
||||||
return parts
|
const text = part == null ? '' : String(part);
|
||||||
.map((part) => {
|
return `${signature}${text.length}:${text}|`;
|
||||||
const text = part == null ? '' : String(part);
|
|
||||||
return `${text.length}:${text}`;
|
|
||||||
})
|
|
||||||
.join('|');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildSidebarTeamsSignature(teams: readonly TeamSummary[]): string {
|
function buildSidebarTeamsSignature(teams: readonly TeamSummary[]): string {
|
||||||
const parts: unknown[] = [];
|
let signature = '';
|
||||||
for (const team of teams) {
|
for (const team of teams) {
|
||||||
parts.push(
|
signature = appendSignaturePart(signature, team.teamName);
|
||||||
team.teamName,
|
signature = appendSignaturePart(signature, team.displayName);
|
||||||
team.displayName,
|
signature = appendSignaturePart(signature, team.projectPath);
|
||||||
team.projectPath,
|
signature = appendSignaturePart(signature, team.lastActivity);
|
||||||
team.lastActivity,
|
signature = appendSignaturePart(signature, team.partialLaunchFailure ? 1 : 0);
|
||||||
team.partialLaunchFailure ? 1 : 0,
|
signature = appendSignaturePart(signature, team.teamLaunchState);
|
||||||
team.teamLaunchState
|
|
||||||
);
|
|
||||||
for (const member of team.members ?? []) {
|
for (const member of team.members ?? []) {
|
||||||
const colorMember = member as TeamMemberColorInput;
|
const colorMember = member as TeamMemberColorInput;
|
||||||
parts.push(colorMember.name, colorMember.color, colorMember.agentType, colorMember.removedAt);
|
signature = appendSignaturePart(signature, colorMember.name);
|
||||||
|
signature = appendSignaturePart(signature, colorMember.color);
|
||||||
|
signature = appendSignaturePart(signature, colorMember.agentType);
|
||||||
|
signature = appendSignaturePart(signature, colorMember.removedAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return encodeSignatureParts(parts);
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildTeamNamesIdentityKey(teams: readonly TeamSummary[]): string {
|
||||||
|
let signature = '';
|
||||||
|
for (const team of teams) {
|
||||||
|
signature = appendSignaturePart(signature, team.teamName);
|
||||||
|
}
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectLeadOfflineTeamNames(
|
||||||
|
leadActivityByTeam: Partial<Record<string, LeadActivityState>>
|
||||||
|
): string[] {
|
||||||
|
const offlineTeamNames: string[] = [];
|
||||||
|
for (const [teamName, activity] of Object.entries(leadActivityByTeam)) {
|
||||||
|
if (activity === 'offline') {
|
||||||
|
offlineTeamNames.push(teamName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offlineTeamNames.sort();
|
||||||
|
|
||||||
|
let signature = '';
|
||||||
|
for (const teamName of offlineTeamNames) {
|
||||||
|
signature = appendSignaturePart(signature, teamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signature === cachedLeadOfflineTeamsSignature) {
|
||||||
|
return cachedLeadOfflineTeamNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
cachedLeadOfflineTeamsSignature = signature;
|
||||||
|
cachedLeadOfflineTeamNames = offlineTeamNames;
|
||||||
|
return cachedLeadOfflineTeamNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectSidebarTeamsDerived(teams: readonly TeamSummary[]): SidebarTeamsDerived {
|
function selectSidebarTeamsDerived(teams: readonly TeamSummary[]): SidebarTeamsDerived {
|
||||||
|
|
@ -260,7 +292,7 @@ function selectSidebarTeamsDerived(teams: readonly TeamSummary[]): SidebarTeamsD
|
||||||
|
|
||||||
cachedSidebarTeamsSignature = signature;
|
cachedSidebarTeamsSignature = signature;
|
||||||
cachedSidebarTeamsDerived = {
|
cachedSidebarTeamsDerived = {
|
||||||
identityKey: encodeSignatureParts(teams.map((team) => team.teamName)),
|
identityKey: buildTeamNamesIdentityKey(teams),
|
||||||
filterTeams: teams.map((team) => ({
|
filterTeams: teams.map((team) => ({
|
||||||
teamName: team.teamName,
|
teamName: team.teamName,
|
||||||
displayName: team.displayName,
|
displayName: team.displayName,
|
||||||
|
|
@ -865,7 +897,7 @@ export const GlobalTaskList = memo(function GlobalTaskList({
|
||||||
repositoryGroupsError,
|
repositoryGroupsError,
|
||||||
provisioningRuns,
|
provisioningRuns,
|
||||||
currentProvisioningRunIdByTeam,
|
currentProvisioningRunIdByTeam,
|
||||||
leadActivityByTeam,
|
leadOfflineTeamNames,
|
||||||
} = useStore(
|
} = useStore(
|
||||||
useShallow((s) => ({
|
useShallow((s) => ({
|
||||||
globalTasks: s.globalTasks,
|
globalTasks: s.globalTasks,
|
||||||
|
|
@ -886,7 +918,7 @@ export const GlobalTaskList = memo(function GlobalTaskList({
|
||||||
repositoryGroupsError: s.repositoryGroupsError,
|
repositoryGroupsError: s.repositoryGroupsError,
|
||||||
provisioningRuns: s.provisioningRuns,
|
provisioningRuns: s.provisioningRuns,
|
||||||
currentProvisioningRunIdByTeam: s.currentProvisioningRunIdByTeam,
|
currentProvisioningRunIdByTeam: s.currentProvisioningRunIdByTeam,
|
||||||
leadActivityByTeam: s.leadActivityByTeam,
|
leadOfflineTeamNames: selectLeadOfflineTeamNames(s.leadActivityByTeam),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
const sidebarTeams = useStore((s) => selectSidebarTeamsDerived(s.teams));
|
const sidebarTeams = useStore((s) => selectSidebarTeamsDerived(s.teams));
|
||||||
|
|
@ -1007,6 +1039,7 @@ export const GlobalTaskList = memo(function GlobalTaskList({
|
||||||
|
|
||||||
const offlineTeamNames = useMemo(() => {
|
const offlineTeamNames = useMemo(() => {
|
||||||
const result = new Set<string>();
|
const result = new Set<string>();
|
||||||
|
const leadOfflineTeams = new Set(leadOfflineTeamNames);
|
||||||
if (aliveTeamsInitialized) {
|
if (aliveTeamsInitialized) {
|
||||||
const teamSummariesByName = new Map<string, TeamSummary>();
|
const teamSummariesByName = new Map<string, TeamSummary>();
|
||||||
for (const team of sidebarTeams.statusSummaries) {
|
for (const team of sidebarTeams.statusSummaries) {
|
||||||
|
|
@ -1019,29 +1052,31 @@ export const GlobalTaskList = memo(function GlobalTaskList({
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const team of teamSummariesByName.values()) {
|
for (const team of teamSummariesByName.values()) {
|
||||||
|
if (leadOfflineTeams.has(team.teamName)) {
|
||||||
|
result.add(team.teamName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const status = resolveTeamStatus(
|
const status = resolveTeamStatus(
|
||||||
team,
|
team,
|
||||||
team.teamName,
|
team.teamName,
|
||||||
aliveTeams,
|
aliveTeams,
|
||||||
getCurrentProvisioningProgressForTeam(provisioningState, team.teamName),
|
getCurrentProvisioningProgressForTeam(provisioningState, team.teamName),
|
||||||
leadActivityByTeam
|
{}
|
||||||
);
|
);
|
||||||
if (!isTeamListStatusRunning(status)) {
|
if (!isTeamListStatusRunning(status)) {
|
||||||
result.add(team.teamName);
|
result.add(team.teamName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const [teamName, activity] of Object.entries(leadActivityByTeam)) {
|
for (const teamName of leadOfflineTeamNames) {
|
||||||
if (activity === 'offline') {
|
result.add(teamName);
|
||||||
result.add(teamName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [
|
}, [
|
||||||
aliveTeams,
|
aliveTeams,
|
||||||
aliveTeamsInitialized,
|
aliveTeamsInitialized,
|
||||||
globalTasks,
|
globalTasks,
|
||||||
leadActivityByTeam,
|
leadOfflineTeamNames,
|
||||||
provisioningState,
|
provisioningState,
|
||||||
sidebarTeams.statusSummaries,
|
sidebarTeams.statusSummaries,
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue