2021-10-19 18:13:18 +00:00
|
|
|
import React, { useContext, useState } from "react";
|
|
|
|
import { useQuery } from "react-query";
|
2021-07-12 17:15:47 +00:00
|
|
|
import paths from "router/paths";
|
|
|
|
import { Link } from "react-router";
|
2021-10-19 18:13:18 +00:00
|
|
|
import { AppContext } from "context/app";
|
|
|
|
import { find } from "lodash";
|
|
|
|
|
2021-11-12 14:27:05 +00:00
|
|
|
import hostSummaryAPI from "services/entities/host_summary";
|
2021-10-19 18:13:18 +00:00
|
|
|
import teamsAPI from "services/entities/teams";
|
2021-11-12 14:27:05 +00:00
|
|
|
import { IHostSummary, IHostSummaryPlatforms } from "interfaces/host_summary";
|
2021-10-19 18:13:18 +00:00
|
|
|
import { ISoftware } from "interfaces/software";
|
2021-11-12 14:27:05 +00:00
|
|
|
import { ITeam } from "interfaces/team";
|
2021-10-19 18:13:18 +00:00
|
|
|
|
|
|
|
import TeamsDropdown from "components/TeamsDropdown";
|
|
|
|
import Button from "components/buttons/Button";
|
2021-10-26 19:47:34 +00:00
|
|
|
import InfoCard from "./components/InfoCard";
|
2021-11-12 14:27:05 +00:00
|
|
|
import HostsStatus from "./cards/HostsStatus";
|
2021-10-26 19:47:34 +00:00
|
|
|
import HostsSummary from "./cards/HostsSummary";
|
|
|
|
import ActivityFeed from "./cards/ActivityFeed";
|
|
|
|
import Software from "./cards/Software";
|
|
|
|
import LearnFleet from "./cards/LearnFleet";
|
|
|
|
import WelcomeHost from "./cards/WelcomeHost";
|
2021-07-26 20:04:35 +00:00
|
|
|
import LinkArrow from "../../../assets/images/icon-arrow-right-vibrant-blue-10x18@2x.png";
|
2021-10-19 18:13:18 +00:00
|
|
|
|
|
|
|
interface ITeamsResponse {
|
|
|
|
teams: ITeam[];
|
|
|
|
}
|
2021-07-12 17:15:47 +00:00
|
|
|
|
2021-07-26 20:04:35 +00:00
|
|
|
const baseClass = "homepage";
|
2021-07-12 17:15:47 +00:00
|
|
|
|
2021-11-09 20:48:23 +00:00
|
|
|
const TAGGED_TEMPLATES = {
|
|
|
|
hostsByTeamRoute: (teamId: number | undefined | null) => {
|
|
|
|
return `${teamId ? `/?team_id=${teamId}` : ""}`;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-07-26 20:04:35 +00:00
|
|
|
const Homepage = (): JSX.Element => {
|
2021-07-12 17:15:47 +00:00
|
|
|
const { MANAGE_HOSTS } = paths;
|
2021-10-26 19:47:34 +00:00
|
|
|
const {
|
|
|
|
config,
|
|
|
|
currentTeam,
|
|
|
|
isPremiumTier,
|
|
|
|
isPreviewMode,
|
|
|
|
setCurrentTeam,
|
|
|
|
} = useContext(AppContext);
|
2021-10-19 18:13:18 +00:00
|
|
|
|
|
|
|
const [isSoftwareModalOpen, setIsSoftwareModalOpen] = useState<boolean>(
|
|
|
|
false
|
|
|
|
);
|
2021-11-12 14:27:05 +00:00
|
|
|
const [totalCount, setTotalCount] = useState<string | undefined>();
|
|
|
|
const [macCount, setMacCount] = useState<string>("0");
|
|
|
|
const [windowsCount, setWindowsCount] = useState<string>("0");
|
|
|
|
const [onlineCount, setOnlineCount] = useState<string | undefined>();
|
|
|
|
const [offlineCount, setOfflineCount] = useState<string | undefined>();
|
|
|
|
const [newCount, setNewCount] = useState<string | undefined>();
|
2021-10-19 18:13:18 +00:00
|
|
|
|
|
|
|
const { data: teams, isLoading: isLoadingTeams } = useQuery<
|
|
|
|
ITeamsResponse,
|
|
|
|
Error,
|
|
|
|
ITeam[]
|
|
|
|
>(["teams"], () => teamsAPI.loadAll(), {
|
|
|
|
enabled: !!isPremiumTier,
|
|
|
|
select: (data: ITeamsResponse) => data.teams,
|
|
|
|
});
|
|
|
|
|
|
|
|
const handleTeamSelect = (teamId: number) => {
|
|
|
|
const selectedTeam = find(teams, ["id", teamId]);
|
|
|
|
setCurrentTeam(selectedTeam);
|
|
|
|
};
|
|
|
|
|
2021-11-12 14:27:05 +00:00
|
|
|
useQuery<IHostSummary, Error, IHostSummary>(
|
|
|
|
["host summary", currentTeam],
|
|
|
|
() => {
|
|
|
|
return hostSummaryAPI.getSummary(currentTeam?.id);
|
|
|
|
},
|
|
|
|
{
|
|
|
|
select: (data: IHostSummary) => data,
|
|
|
|
onSuccess: (data: any) => {
|
|
|
|
setTotalCount(data.totals_hosts_count.toLocaleString("en-US"));
|
|
|
|
setOnlineCount(data.online_count.toLocaleString("en-US"));
|
|
|
|
setOfflineCount(data.offline_count.toLocaleString("en-US"));
|
|
|
|
setNewCount(data.new_count.toLocaleString("en-US"));
|
|
|
|
const macHosts = data.platforms?.find(
|
|
|
|
(platform: IHostSummaryPlatforms) => platform.platform === "darwin"
|
|
|
|
) || { platform: "darwin", hosts_count: 0 };
|
|
|
|
setMacCount(macHosts.hosts_count.toLocaleString("en-US"));
|
|
|
|
const windowsHosts = data.platforms?.find(
|
|
|
|
(platform: IHostSummaryPlatforms) => platform.platform === "windows"
|
|
|
|
) || { platform: "windows", hosts_count: 0 };
|
|
|
|
setWindowsCount(windowsHosts.hosts_count.toLocaleString("en-US"));
|
|
|
|
},
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2021-07-12 17:15:47 +00:00
|
|
|
return (
|
|
|
|
<div className={baseClass}>
|
2021-10-18 13:36:43 +00:00
|
|
|
<div className={`${baseClass}__header-wrap`}>
|
|
|
|
<div className={`${baseClass}__header`}>
|
2021-10-19 18:13:18 +00:00
|
|
|
{isPremiumTier ? (
|
|
|
|
<TeamsDropdown
|
|
|
|
currentTeamId={currentTeam?.id || 0}
|
|
|
|
isLoading={isLoadingTeams}
|
|
|
|
teams={teams || []}
|
|
|
|
onChange={(newSelectedValue: number) =>
|
|
|
|
handleTeamSelect(newSelectedValue)
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<h1 className={`${baseClass}__title`}>
|
|
|
|
<span>{config?.org_name}</span>
|
|
|
|
</h1>
|
|
|
|
)}
|
2021-07-12 17:15:47 +00:00
|
|
|
</div>
|
2021-10-18 13:36:43 +00:00
|
|
|
</div>
|
|
|
|
<div className={`${baseClass}__section one-column`}>
|
2021-10-26 19:47:34 +00:00
|
|
|
<InfoCard
|
|
|
|
title="Hosts"
|
2021-11-09 20:48:23 +00:00
|
|
|
action={{
|
|
|
|
type: "link",
|
|
|
|
to:
|
|
|
|
MANAGE_HOSTS + TAGGED_TEMPLATES.hostsByTeamRoute(currentTeam?.id),
|
|
|
|
text: "View all hosts",
|
|
|
|
}}
|
2021-11-12 14:27:05 +00:00
|
|
|
total_host_count={totalCount}
|
2021-10-26 19:47:34 +00:00
|
|
|
>
|
2021-11-12 14:27:05 +00:00
|
|
|
<HostsSummary
|
|
|
|
currentTeamId={currentTeam?.id}
|
|
|
|
macCount={macCount}
|
|
|
|
windowsCount={windowsCount}
|
|
|
|
/>
|
|
|
|
</InfoCard>
|
|
|
|
</div>
|
|
|
|
<div className={`${baseClass}__section one-column`}>
|
|
|
|
<InfoCard title="">
|
|
|
|
<HostsStatus
|
|
|
|
onlineCount={onlineCount}
|
|
|
|
offlineCount={offlineCount}
|
|
|
|
newCount={newCount}
|
|
|
|
/>
|
2021-10-26 19:47:34 +00:00
|
|
|
</InfoCard>
|
2021-10-18 13:36:43 +00:00
|
|
|
</div>
|
2021-10-26 19:47:34 +00:00
|
|
|
{isPreviewMode && (
|
|
|
|
<div className={`${baseClass}__section two-column`}>
|
|
|
|
<InfoCard title="Welcome to Fleet">
|
|
|
|
<WelcomeHost />
|
|
|
|
</InfoCard>
|
|
|
|
<InfoCard title="Learn how to use Fleet">
|
|
|
|
<LearnFleet />
|
|
|
|
</InfoCard>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{!isPreviewMode && !currentTeam && (
|
2021-10-19 18:13:18 +00:00
|
|
|
<div className={`${baseClass}__section one-column`}>
|
2021-10-26 19:47:34 +00:00
|
|
|
<InfoCard title="Activity">
|
2021-10-19 18:13:18 +00:00
|
|
|
<ActivityFeed />
|
2021-10-26 19:47:34 +00:00
|
|
|
</InfoCard>
|
2021-10-19 18:13:18 +00:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{/* TODO: Re-add this commented out section once the /software API is running */}
|
|
|
|
{/* <div className={`
|
|
|
|
${baseClass}__section
|
|
|
|
${currentTeam ? 'one' : 'two'}-column
|
|
|
|
`}>
|
|
|
|
{!currentTeam && (
|
2021-10-26 19:47:34 +00:00
|
|
|
<InfoCard
|
|
|
|
title="Software"
|
|
|
|
action={{
|
|
|
|
type: button,
|
|
|
|
text: "View all software",
|
|
|
|
onClick: () => setIsSoftwareModalOpen(true)
|
|
|
|
}}
|
|
|
|
>
|
2021-10-19 18:13:18 +00:00
|
|
|
<Software
|
|
|
|
isModalOpen={isSoftwareModalOpen}
|
|
|
|
setIsSoftwareModalOpen={setIsSoftwareModalOpen}
|
|
|
|
/>
|
2021-10-26 19:47:34 +00:00
|
|
|
</InfoCard>
|
2021-10-19 18:13:18 +00:00
|
|
|
)}
|
2021-10-26 19:47:34 +00:00
|
|
|
<InfoCard title="Activity">
|
2021-10-18 13:36:43 +00:00
|
|
|
<ActivityFeed />
|
2021-10-26 19:47:34 +00:00
|
|
|
</InfoCard>
|
2021-10-19 18:13:18 +00:00
|
|
|
</div> */}
|
2021-07-12 17:15:47 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2021-07-26 20:04:35 +00:00
|
|
|
export default Homepage;
|