mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 01:18:42 +00:00
UI – Update empty Software versions table when installable software present (#21118)
## Addresses 1a of #21053 <img width="1498" alt="Screenshot 2024-08-06 at 7 56 38 PM" src="https://github.com/user-attachments/assets/d2e97e07-acd7-4f0b-a609-b8b9546a742d"> - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
parent
c221fa3eee
commit
50ba783a25
5 changed files with 58 additions and 9 deletions
|
|
@ -60,6 +60,7 @@ interface ISoftwareTableProps {
|
|||
router: InjectedRouter;
|
||||
data?: ISoftwareTitlesResponse | ISoftwareVersionsResponse;
|
||||
showVersions: boolean;
|
||||
installableSoftwareExists: boolean;
|
||||
isSoftwareEnabled: boolean;
|
||||
query: string;
|
||||
perPage: number;
|
||||
|
|
@ -78,6 +79,7 @@ const SoftwareTable = ({
|
|||
router,
|
||||
data,
|
||||
showVersions,
|
||||
installableSoftwareExists,
|
||||
isSoftwareEnabled,
|
||||
query,
|
||||
perPage,
|
||||
|
|
@ -335,6 +337,8 @@ const SoftwareTable = ({
|
|||
softwareFilter={softwareFilter}
|
||||
isSoftwareDisabled={!isSoftwareEnabled}
|
||||
noSearchQuery={query === ""}
|
||||
isCollectingSoftware={data?.counts_updated_at === null}
|
||||
installableSoftwareExists={installableSoftwareExists}
|
||||
/>
|
||||
)}
|
||||
defaultSortHeader={orderKey}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ const SoftwareTitles = ({
|
|||
}: ISoftwareTitlesProps) => {
|
||||
const showVersions = location.pathname === PATHS.SOFTWARE_VERSIONS;
|
||||
|
||||
// request to get software data
|
||||
// for Titles view, request to get software data
|
||||
const {
|
||||
data: titlesData,
|
||||
isFetching: isTitlesFetching,
|
||||
|
|
@ -94,7 +94,9 @@ const SoftwareTitles = ({
|
|||
}
|
||||
);
|
||||
|
||||
// request to get software versions data
|
||||
// For Versions view, request software versions data. If empty, request titles available for
|
||||
// install to determine empty state copy
|
||||
|
||||
const {
|
||||
data: versionsData,
|
||||
isFetching: isVersionsFetching,
|
||||
|
|
@ -127,11 +129,45 @@ const SoftwareTitles = ({
|
|||
}
|
||||
);
|
||||
|
||||
if (isTitlesLoading || isVersionsLoading) {
|
||||
const {
|
||||
data: titlesAvailableForInstallResponse,
|
||||
isFetching: isTitlesAFIFetching,
|
||||
isLoading: isTitlesAFILoading,
|
||||
isError: isTitlesAFIError,
|
||||
} = useQuery<
|
||||
ISoftwareTitlesResponse,
|
||||
Error,
|
||||
ISoftwareTitlesResponse,
|
||||
[ISoftwareTitlesQueryKey]
|
||||
>(
|
||||
[
|
||||
{
|
||||
scope: "software-titles",
|
||||
page: 1,
|
||||
perPage,
|
||||
query: "",
|
||||
orderDirection,
|
||||
orderKey,
|
||||
teamId,
|
||||
availableForInstall: true,
|
||||
},
|
||||
],
|
||||
({ queryKey: [queryKey] }) =>
|
||||
softwareAPI.getSoftwareTitles(omit(queryKey, "scope")),
|
||||
{
|
||||
...QUERY_OPTIONS,
|
||||
enabled:
|
||||
location.pathname === PATHS.SOFTWARE_VERSIONS &&
|
||||
versionsData &&
|
||||
versionsData.count === 0,
|
||||
}
|
||||
);
|
||||
|
||||
if (isTitlesLoading || isVersionsLoading || isTitlesAFILoading) {
|
||||
return <Spinner />;
|
||||
}
|
||||
|
||||
if (isTitlesError || isVersionsError) {
|
||||
if (isTitlesError || isVersionsError || isTitlesAFIError) {
|
||||
return <TableDataError className={`${baseClass}__table-error`} />;
|
||||
}
|
||||
|
||||
|
|
@ -141,6 +177,7 @@ const SoftwareTitles = ({
|
|||
router={router}
|
||||
data={showVersions ? versionsData : titlesData}
|
||||
showVersions={showVersions}
|
||||
installableSoftwareExists={!!titlesAvailableForInstallResponse?.count}
|
||||
isSoftwareEnabled={isSoftwareEnabled}
|
||||
query={query}
|
||||
perPage={perPage}
|
||||
|
|
@ -149,7 +186,9 @@ const SoftwareTitles = ({
|
|||
softwareFilter={softwareFilter}
|
||||
currentPage={currentPage}
|
||||
teamId={teamId}
|
||||
isLoading={isTitlesFetching || isVersionsFetching}
|
||||
isLoading={
|
||||
isTitlesFetching || isVersionsFetching || isTitlesAFIFetching
|
||||
}
|
||||
resetPageIndex={resetPageIndex}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export interface IEmptySoftwareTableProps {
|
|||
noSearchQuery?: boolean;
|
||||
/** isCollectingSoftware is only used on the Dashboard page with a TODO to revisit */
|
||||
isCollectingSoftware?: boolean;
|
||||
/** true if the team has any software installers or VPP apps available to install on hosts */
|
||||
installableSoftwareExists?: boolean;
|
||||
}
|
||||
|
||||
const generateTypeText = (
|
||||
|
|
@ -38,6 +40,7 @@ const EmptySoftwareTable = ({
|
|||
isSoftwareDisabled,
|
||||
noSearchQuery,
|
||||
isCollectingSoftware,
|
||||
installableSoftwareExists,
|
||||
}: IEmptySoftwareTableProps): JSX.Element => {
|
||||
const softwareTypeText = generateTypeText(tableName, softwareFilter);
|
||||
|
||||
|
|
@ -50,10 +53,14 @@ const EmptySoftwareTable = ({
|
|||
emptySoftware.header = "No software detected";
|
||||
}
|
||||
|
||||
if (softwareFilter === "allSoftware" && installableSoftwareExists) {
|
||||
emptySoftware.header = "No software detected";
|
||||
emptySoftware.info = "Install software on your hosts to see versions.";
|
||||
}
|
||||
|
||||
if (isCollectingSoftware) {
|
||||
emptySoftware.header = "No software detected";
|
||||
emptySoftware.info =
|
||||
"This report is updated every hour to protect the performance of your devices.";
|
||||
emptySoftware.info = `Expecting to see ${softwareTypeText}? Check back later.`;
|
||||
}
|
||||
|
||||
if (isSoftwareDisabled) {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ type IInstalledVersionsCellProps = CellProps<
|
|||
IHostSoftware["installed_versions"]
|
||||
>;
|
||||
type IVulnerabilitiesCellProps = IInstalledVersionsCellProps;
|
||||
// type IActionsCellProps = CellProps<IHostSoftware, IHostSoftware["id"]>;
|
||||
|
||||
const generateActions = ({
|
||||
userHasSWInstallPermission,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export interface ISoftwareVersionsQueryKey extends ISoftwareApiParams {
|
|||
|
||||
export interface ISoftwareTitlesQueryKey extends ISoftwareApiParams {
|
||||
// used to trigger software refetches from sibling pages
|
||||
addedSoftwareToken: string | null;
|
||||
addedSoftwareToken?: string | null;
|
||||
scope: "software-titles";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue