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);
+ }
}
}