forked from wrenn/wrenn
Fix team name blink on navigation by lifting teams into a singleton store
Teams list was fetched on every Sidebar mount (each page navigation), causing a flash from '…' to the real name on every tab switch. Move teams into a module-level reactive store (teams.svelte.ts) that fetches once per session and is shared between Sidebar and the team page.
This commit is contained in:
@ -3,7 +3,8 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { Popover } from 'bits-ui';
|
||||
import { auth } from '$lib/auth.svelte';
|
||||
import { listTeams, createTeam, switchTeam, type TeamWithRole } from '$lib/api/team';
|
||||
import { teams as teamsStore } from '$lib/teams.svelte';
|
||||
import { createTeam, switchTeam } from '$lib/api/team';
|
||||
import {
|
||||
IconMonitor,
|
||||
IconBox,
|
||||
@ -25,9 +26,7 @@
|
||||
|
||||
let teamPopoverOpen = $state(false);
|
||||
|
||||
// Real teams from API
|
||||
let teams = $state<TeamWithRole[]>([]);
|
||||
let currentTeamName = $derived(teams.find((t) => t.id === auth.teamId)?.name ?? '');
|
||||
let currentTeamName = $derived(teamsStore.list.find((t) => t.id === auth.teamId)?.name ?? '');
|
||||
let userName = $derived(auth.email ?? '');
|
||||
|
||||
// Create team dialog
|
||||
@ -69,10 +68,7 @@
|
||||
}
|
||||
|
||||
async function fetchTeams() {
|
||||
const result = await listTeams();
|
||||
if (result.ok) {
|
||||
teams = result.data;
|
||||
}
|
||||
await teamsStore.fetch();
|
||||
}
|
||||
|
||||
async function handleSwitchTeam(teamId: string) {
|
||||
@ -180,7 +176,7 @@
|
||||
>
|
||||
Teams
|
||||
</div>
|
||||
{#each teams as team (team.id)}
|
||||
{#each teamsStore.list as team (team.id)}
|
||||
<button
|
||||
class="flex w-full items-center gap-2.5 rounded-[var(--radius-input)] px-2.5 py-2 text-ui transition-colors duration-150 hover:bg-[var(--color-bg-3)] {team.id ===
|
||||
auth.teamId
|
||||
|
||||
31
frontend/src/lib/teams.svelte.ts
Normal file
31
frontend/src/lib/teams.svelte.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { listTeams, type TeamWithRole } from '$lib/api/team';
|
||||
|
||||
function createTeamsStore() {
|
||||
let teams = $state<TeamWithRole[]>([]);
|
||||
let loaded = $state(false);
|
||||
|
||||
return {
|
||||
get list() {
|
||||
return teams;
|
||||
},
|
||||
get loaded() {
|
||||
return loaded;
|
||||
},
|
||||
async fetch() {
|
||||
if (loaded) return;
|
||||
const result = await listTeams();
|
||||
if (result.ok) {
|
||||
teams = result.data;
|
||||
loaded = true;
|
||||
}
|
||||
},
|
||||
// Call after mutating teams (create/switch triggers a full reload, but
|
||||
// adding a team locally avoids a flicker in the popover list).
|
||||
set(newTeams: TeamWithRole[]) {
|
||||
teams = newTeams;
|
||||
loaded = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const teams = createTeamsStore();
|
||||
@ -17,9 +17,9 @@
|
||||
searchUsers,
|
||||
type TeamInfo,
|
||||
type TeamMember,
|
||||
type TeamWithRole,
|
||||
type UserSearchResult
|
||||
} from '$lib/api/team';
|
||||
import { teams as teamsStore } from '$lib/teams.svelte';
|
||||
|
||||
let collapsed = $state(
|
||||
typeof window !== 'undefined'
|
||||
@ -30,12 +30,11 @@
|
||||
// Page data
|
||||
let team = $state<TeamInfo | null>(null);
|
||||
let members = $state<TeamMember[]>([]);
|
||||
let allTeams = $state<TeamWithRole[]>([]);
|
||||
let loading = $state(true);
|
||||
let error = $state<string | null>(null);
|
||||
|
||||
// True when this is the user's only team — deleting/leaving would leave them teamless
|
||||
let isLastTeam = $derived(allTeams.length <= 1);
|
||||
let isLastTeam = $derived(teamsStore.list.length <= 1);
|
||||
|
||||
// Current user's role — derived from members list
|
||||
let myRole = $derived(members.find((m) => m.user_id === auth.userId)?.role ?? 'member');
|
||||
@ -86,9 +85,9 @@
|
||||
loading = false;
|
||||
return;
|
||||
}
|
||||
const [teamResult, teamsResult] = await Promise.all([
|
||||
const [teamResult] = await Promise.all([
|
||||
getTeam(auth.teamId),
|
||||
listTeams()
|
||||
teamsStore.fetch()
|
||||
]);
|
||||
if (teamResult.ok) {
|
||||
team = teamResult.data.team;
|
||||
@ -96,9 +95,6 @@
|
||||
} else {
|
||||
error = teamResult.error;
|
||||
}
|
||||
if (teamsResult.ok) {
|
||||
allTeams = teamsResult.data;
|
||||
}
|
||||
loading = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user