diff --git a/app/actions/definitions/teams.tsx b/app/actions/definitions/teams.tsx
index 3eae35035..fcb8c9d85 100644
--- a/app/actions/definitions/teams.tsx
+++ b/app/actions/definitions/teams.tsx
@@ -2,42 +2,46 @@ import { PlusIcon } from "outline-icons";
import * as React from "react";
import styled from "styled-components";
import { stringToColor } from "@shared/utils/color";
+import RootStore from "~/stores/RootStore";
import TeamNew from "~/scenes/TeamNew";
import TeamLogo from "~/components/TeamLogo";
import { createAction } from "~/actions";
-import { loadSessionsFromCookie } from "~/hooks/useSessions";
import { TeamSection } from "../sections";
-export const switchTeamList = getSessions().map((session) => {
- return createAction({
- name: session.name,
- section: TeamSection,
- keywords: "change switch workspace organization team",
- icon: () => (
-
- ),
- visible: ({ currentTeamId }) => currentTeamId !== session.teamId,
- perform: () => (window.location.href = session.url),
- });
-});
+export const createTeamsList = ({ stores }: { stores: RootStore }) => {
+ return (
+ stores.auth.availableTeams?.map((session) =>
+ createAction({
+ name: session.name,
+ section: TeamSection,
+ keywords: "change switch workspace organization team",
+ icon: () => (
+
+ ),
+ visible: ({ currentTeamId }) => currentTeamId !== session.id,
+ perform: () => (window.location.href = session.url),
+ })
+ ) ?? []
+ );
+};
-const switchTeam = createAction({
+export const switchTeam = createAction({
name: ({ t }) => t("Switch workspace"),
placeholder: ({ t }) => t("Select a workspace"),
keywords: "change switch workspace organization team",
section: TeamSection,
- visible: ({ currentTeamId }) =>
- getSessions({ exclude: currentTeamId }).length > 0,
- children: switchTeamList,
+ visible: ({ stores }) =>
+ !!stores.auth.availableTeams && stores.auth.availableTeams?.length > 1,
+ children: createTeamsList,
});
export const createTeam = createAction({
@@ -60,14 +64,6 @@ export const createTeam = createAction({
},
});
-function getSessions(params?: { exclude?: string }) {
- const sessions = loadSessionsFromCookie();
- const otherSessions = sessions.filter(
- (session) => session.teamId !== params?.exclude
- );
- return otherSessions;
-}
-
const StyledTeamLogo = styled(TeamLogo)`
border-radius: 2px;
border: 0;
diff --git a/app/hooks/useSessions.ts b/app/hooks/useSessions.ts
deleted file mode 100644
index 83f64aa83..000000000
--- a/app/hooks/useSessions.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from "react";
-import { getCookie } from "tiny-cookie";
-
-type Session = {
- url: string;
- logoUrl: string;
- name: string;
- teamId: string;
-};
-
-export function loadSessionsFromCookie(): Session[] {
- const sessions = JSON.parse(getCookie("sessions") || "{}");
- return Object.keys(sessions).map((teamId) => ({
- teamId,
- ...sessions[teamId],
- }));
-}
-
-export default function useSessions(): [Session[], () => void] {
- const [sessions, setSessions] = React.useState(loadSessionsFromCookie);
- const reload = React.useCallback(() => {
- setSessions(loadSessionsFromCookie());
- }, []);
- return [sessions, reload];
-}
diff --git a/app/menus/OrganizationMenu.tsx b/app/menus/OrganizationMenu.tsx
index f7778b32f..2c1d11578 100644
--- a/app/menus/OrganizationMenu.tsx
+++ b/app/menus/OrganizationMenu.tsx
@@ -5,23 +5,19 @@ import { MenuButton, useMenuState } from "reakit/Menu";
import ContextMenu from "~/components/ContextMenu";
import Template from "~/components/ContextMenu/Template";
import { navigateToSettings, logout } from "~/actions/definitions/navigation";
-import { createTeam, switchTeamList } from "~/actions/definitions/teams";
-import useCurrentTeam from "~/hooks/useCurrentTeam";
+import { createTeam, createTeamsList } from "~/actions/definitions/teams";
import usePrevious from "~/hooks/usePrevious";
-import useSessions from "~/hooks/useSessions";
import useStores from "~/hooks/useStores";
import separator from "~/menus/separator";
const OrganizationMenu: React.FC = ({ children }) => {
- const [sessions] = useSessions();
const menu = useMenuState({
unstable_offset: [4, -4],
placement: "bottom-start",
modal: true,
});
- const { ui } = useStores();
- const { theme } = ui;
- const team = useCurrentTeam();
+ const stores = useStores();
+ const { theme } = stores.ui;
const previousTheme = usePrevious(theme);
const { t } = useTranslation();
@@ -35,13 +31,13 @@ const OrganizationMenu: React.FC = ({ children }) => {
// menu is not cached at all.
const actions = React.useMemo(() => {
return [
- ...switchTeamList,
+ ...createTeamsList({ stores }),
createTeam,
separator(),
navigateToSettings,
logout,
];
- }, [team.id, sessions]);
+ }, [stores]);
return (
<>
diff --git a/app/stores/AuthStore.ts b/app/stores/AuthStore.ts
index 3f745098d..9b196323c 100644
--- a/app/stores/AuthStore.ts
+++ b/app/stores/AuthStore.ts
@@ -19,6 +19,13 @@ const NO_REDIRECT_PATHS = ["/", "/create", "/home"];
type PersistedData = {
user?: User;
team?: Team;
+ availableTeams?: {
+ id: string;
+ name: string;
+ avatarUrl: string;
+ url: string;
+ isSignedIn: boolean;
+ }[];
policies?: Policy[];
};
@@ -37,19 +44,28 @@ export type Config = {
export default class AuthStore {
@observable
- user: User | null | undefined;
+ user?: User | null;
@observable
- team: Team | null | undefined;
+ team?: Team | null;
@observable
- token: string | null | undefined;
+ availableTeams?: {
+ id: string;
+ name: string;
+ avatarUrl: string;
+ url: string;
+ isSignedIn: boolean;
+ }[];
+
+ @observable
+ token?: string | null;
@observable
policies: Policy[] = [];
@observable
- lastSignedIn: string | null | undefined;
+ lastSignedIn?: string | null;
@observable
isSaving = false;
@@ -58,7 +74,7 @@ export default class AuthStore {
isSuspended = false;
@observable
- suspendedContactEmail: string | null | undefined;
+ suspendedContactEmail?: string | null;
@observable
config: Config | null | undefined;
@@ -133,6 +149,7 @@ export default class AuthStore {
return {
user: this.user,
team: this.team,
+ availableTeams: this.availableTeams,
policies: this.policies,
};
}
@@ -156,6 +173,7 @@ export default class AuthStore {
const { user, team } = res.data;
this.user = new User(user, this);
this.team = new Team(team, this);
+ this.availableTeams = res.data.availableTeams;
if (env.SENTRY_DSN) {
Sentry.configureScope(function (scope) {
@@ -214,6 +232,9 @@ export default class AuthStore {
runInAction("AuthStore#updateUser", () => {
this.user = null;
this.team = null;
+ this.availableTeams = this.availableTeams?.filter(
+ (team) => team.id !== this.team?.id
+ );
this.policies = [];
this.token = null;
});