diff --git a/app/actions/definitions/teams.tsx b/app/actions/definitions/teams.tsx
new file mode 100644
index 000000000..799c6a522
--- /dev/null
+++ b/app/actions/definitions/teams.tsx
@@ -0,0 +1,40 @@
+import * as React from "react";
+import styled from "styled-components";
+import { createAction } from "~/actions";
+import { loadSessionsFromCookie } from "~/hooks/useSessions";
+
+export const changeTeam = createAction({
+ name: ({ t }) => t("Switch team"),
+ placeholder: ({ t }) => t("Select a team"),
+ keywords: "change workspace organization",
+ section: "Account",
+ visible: ({ currentTeamId }) => {
+ const sessions = loadSessionsFromCookie();
+ const otherSessions = sessions.filter(
+ (session) => session.teamId !== currentTeamId
+ );
+ return otherSessions.length > 0;
+ },
+ children: ({ currentTeamId }) => {
+ const sessions = loadSessionsFromCookie();
+ const otherSessions = sessions.filter(
+ (session) => session.teamId !== currentTeamId
+ );
+
+ return otherSessions.map((session) => ({
+ id: session.url,
+ name: session.name,
+ section: "Account",
+ icon: ,
+ perform: () => (window.location.href = session.url),
+ }));
+ },
+});
+
+const Logo = styled("img")`
+ border-radius: 2px;
+ width: 24px;
+ height: 24px;
+`;
+
+export const rootTeamActions = [changeTeam];
diff --git a/app/actions/root.ts b/app/actions/root.ts
index fb19a3868..db4ee3746 100644
--- a/app/actions/root.ts
+++ b/app/actions/root.ts
@@ -3,6 +3,7 @@ import { rootDeveloperActions } from "./definitions/developer";
import { rootDocumentActions } from "./definitions/documents";
import { rootNavigationActions } from "./definitions/navigation";
import { rootSettingsActions } from "./definitions/settings";
+import { rootTeamActions } from "./definitions/teams";
import { rootUserActions } from "./definitions/users";
export default [
@@ -12,4 +13,5 @@ export default [
...rootNavigationActions,
...rootSettingsActions,
...rootDeveloperActions,
+ ...rootTeamActions,
];
diff --git a/app/hooks/useSessions.ts b/app/hooks/useSessions.ts
index 32ddc10c6..83f64aa83 100644
--- a/app/hooks/useSessions.ts
+++ b/app/hooks/useSessions.ts
@@ -8,7 +8,7 @@ type Session = {
teamId: string;
};
-function loadSessionsFromCookie(): Session[] {
+export function loadSessionsFromCookie(): Session[] {
const sessions = JSON.parse(getCookie("sessions") || "{}");
return Object.keys(sessions).map((teamId) => ({
teamId,
diff --git a/app/menus/OrganizationMenu.tsx b/app/menus/OrganizationMenu.tsx
index 5286892d2..ce51e4ce4 100644
--- a/app/menus/OrganizationMenu.tsx
+++ b/app/menus/OrganizationMenu.tsx
@@ -2,11 +2,10 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { MenuButton, useMenuState } from "reakit/Menu";
-import styled from "styled-components";
import ContextMenu from "~/components/ContextMenu";
import Template from "~/components/ContextMenu/Template";
-import { createAction } from "~/actions";
import { navigateToSettings, logout } from "~/actions/definitions/navigation";
+import { changeTeam } from "~/actions/definitions/teams";
import useCurrentTeam from "~/hooks/useCurrentTeam";
import usePrevious from "~/hooks/usePrevious";
import useSessions from "~/hooks/useSessions";
@@ -32,32 +31,11 @@ const OrganizationMenu: React.FC = ({ children }) => {
}
}, [menu, theme, previousTheme]);
+ // NOTE: it's useful to memoize on the team id and session because the action
+ // menu is not cached at all.
const actions = React.useMemo(() => {
- const otherSessions = sessions.filter(
- (session) => session.teamId !== team.id && session.url !== team.url
- );
-
- return [
- navigateToSettings,
- separator(),
- ...(otherSessions.length
- ? [
- createAction({
- name: t("Switch team"),
- section: "account",
- children: otherSessions.map((session) => ({
- id: session.url,
- name: session.name,
- section: "account",
- icon: ,
- perform: () => (window.location.href = session.url),
- })),
- }),
- ]
- : []),
- logout,
- ];
- }, [team.id, team.url, sessions, t]);
+ return [navigateToSettings, separator(), changeTeam, logout];
+ }, [team.id, sessions]);
return (
<>
@@ -69,10 +47,4 @@ const OrganizationMenu: React.FC = ({ children }) => {
);
};
-const Logo = styled("img")`
- border-radius: 2px;
- width: 24px;
- height: 24px;
-`;
-
export default observer(OrganizationMenu);
diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json
index f67953cb3..74f96cde9 100644
--- a/shared/i18n/locales/en_US/translation.json
+++ b/shared/i18n/locales/en_US/translation.json
@@ -52,6 +52,8 @@
"Appearance": "Appearance",
"Change theme": "Change theme",
"Change theme to": "Change theme to",
+ "Switch team": "Switch team",
+ "Select a team": "Select a team",
"Invite people": "Invite people",
"Collection": "Collection",
"Debug": "Debug",
@@ -294,7 +296,6 @@
"New child document": "New child document",
"New document in {{ collectionName }}": "New document in {{ collectionName }}",
"New template": "New template",
- "Switch team": "Switch team",
"Link copied": "Link copied",
"Revision options": "Revision options",
"Restore version": "Restore version",