From 990de127e3de32506f773d2111eafa5ba587eacd Mon Sep 17 00:00:00 2001 From: Nan Yu Date: Fri, 12 Aug 2022 08:11:22 -0400 Subject: [PATCH] feat: add session switching to the root action menu (#3925) * feat: add session switching to the root action menu * minor fixes * stylistic consistency * capitalize account section * minor fix --- app/actions/definitions/teams.tsx | 40 ++++++++++++++++++++++ app/actions/root.ts | 2 ++ app/hooks/useSessions.ts | 2 +- app/menus/OrganizationMenu.tsx | 38 +++----------------- shared/i18n/locales/en_US/translation.json | 3 +- 5 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 app/actions/definitions/teams.tsx 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",