diff --git a/changes/40137-update-default-fleet b/changes/40137-update-default-fleet new file mode 100644 index 0000000000..640fb016d5 --- /dev/null +++ b/changes/40137-update-default-fleet @@ -0,0 +1 @@ +- Updated the default fleet selected when navigating to the dashboard and to Controls diff --git a/frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx b/frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx index c780b0150b..d4ae4299dd 100644 --- a/frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx +++ b/frontend/components/top_nav/SiteTopNav/SiteTopNav.tsx @@ -151,16 +151,14 @@ const SiteTopNav = ({ if (iconName && iconName === "logo") { return (
  • -
    -
    +
  • ); } diff --git a/frontend/context/app.tests.ts b/frontend/context/app.tests.ts new file mode 100644 index 0000000000..ef2de6d757 --- /dev/null +++ b/frontend/context/app.tests.ts @@ -0,0 +1,48 @@ +import createMockUser from "__mocks__/userMock"; + +import { sortAvailableTeams } from "./app"; + +describe("sortAvailableTeams", () => { + it("places Unassigned last for global team users", () => { + const teams = [ + { id: 0, name: "Unassigned" }, + { id: 2, name: "Zebra" }, + { id: 1, name: "Alpha" }, + { id: -1, name: "All fleets" }, + ]; + const result = sortAvailableTeams(teams, createMockUser()); + expect(result.map((t) => t.name)).toEqual([ + "All fleets", + "Alpha", + "Zebra", + "Unassigned", + ]); + }); + + it("does not include All fleets or Unassigned for non-global users", () => { + const teams = [ + { id: 0, name: "Unassigned" }, + { id: 2, name: "Zebra" }, + { id: 1, name: "Alpha" }, + { id: -1, name: "All fleets" }, + ]; + const result = sortAvailableTeams( + teams, + createMockUser({ global_role: null }) + ); + expect(result.map((t) => t.name)).toEqual(["Alpha", "Zebra"]); + }); + + it("sorts named teams alphabetically (case-insensitive)", () => { + const teams = [ + { id: 3, name: "charlie" }, + { id: 1, name: "Alpha" }, + { id: 2, name: "Bravo" }, + ]; + const result = sortAvailableTeams( + teams, + createMockUser({ global_role: null }) + ); + expect(result.map((t) => t.name)).toEqual(["Alpha", "Bravo", "charlie"]); + }); +}); diff --git a/frontend/context/app.tsx b/frontend/context/app.tsx index 3a7d1816c8..c18f706cae 100644 --- a/frontend/context/app.tsx +++ b/frontend/context/app.tsx @@ -339,6 +339,24 @@ const setPermissions = ( }; }; +export const sortAvailableTeams = ( + availableFleets: ITeamSummary[], + user: IUser | null +): ITeamSummary[] => { + const sortedFleets = [...availableFleets] + .sort((a, b) => sort.caseInsensitiveAsc(a.name, b.name)) + .filter( + (t) => + t.name !== APP_CONTEXT_ALL_TEAMS_SUMMARY.name && + t.name !== APP_CONTEXT_NO_TEAM_SUMMARY.name + ); + if (user && permissions.isOnGlobalTeam(user)) { + sortedFleets.unshift(APP_CONTEXT_ALL_TEAMS_SUMMARY); + sortedFleets.push(APP_CONTEXT_NO_TEAM_SUMMARY); + } + return sortedFleets; +}; + const reducer = (state: InitialStateType, action: IAction) => { switch (action.type) { case ACTIONS.SET_USER_SETTINGS: { @@ -349,27 +367,9 @@ const reducer = (state: InitialStateType, action: IAction) => { }; } case ACTIONS.SET_AVAILABLE_TEAMS: { - const { user, availableTeams } = action; - - let sortedTeams = availableTeams.sort( - (a: ITeamSummary, b: ITeamSummary) => - sort.caseInsensitiveAsc(a.name, b.name) - ); - sortedTeams = sortedTeams.filter( - (t) => - t.name !== APP_CONTEXT_ALL_TEAMS_SUMMARY.name && - t.name !== APP_CONTEXT_NO_TEAM_SUMMARY.name - ); - if (user && permissions.isOnGlobalTeam(user)) { - sortedTeams.unshift( - APP_CONTEXT_ALL_TEAMS_SUMMARY, - APP_CONTEXT_NO_TEAM_SUMMARY - ); - } - return { ...state, - availableTeams: sortedTeams, + availableTeams: sortAvailableTeams(action.availableTeams, action.user), }; } case ACTIONS.SET_CURRENT_USER: { diff --git a/frontend/hooks/useTeamIdParam.ts b/frontend/hooks/useTeamIdParam.ts index ff6523ee2b..eced195bf0 100644 --- a/frontend/hooks/useTeamIdParam.ts +++ b/frontend/hooks/useTeamIdParam.ts @@ -1,6 +1,6 @@ import { useCallback, useContext, useEffect, useMemo } from "react"; import { InjectedRouter } from "react-router"; -import { findLastIndex, trimStart } from "lodash"; +import { findLastIndex, sortBy, trimStart } from "lodash"; import { AppContext } from "context/app"; import { TableContext } from "context/table"; @@ -221,8 +221,15 @@ const getDefaultTeam = ({ defaultTeam = userTeams.find((t) => t.id === APP_CONTEXT_ALL_TEAMS_ID); } if (!defaultTeam && includeNoTeam) { - // default to No team when "All teams" not included and no team is included - defaultTeam = userTeams.find((t) => t.id === APP_CONTEXT_NO_TEAM_ID); + // prefer the real fleet with the lowest ID over "Unassigned" + const realFleets = userTeams.filter( + (t) => t.id > APP_CONTEXT_NO_TEAM_ID + ); + if (realFleets.length > 0) { + defaultTeam = sortBy(realFleets, (t) => t.id)[0]; + } else { + defaultTeam = userTeams.find((t) => t.id === APP_CONTEXT_NO_TEAM_ID); + } } }