Fleet UI: Add add variable button, update no results live empty state (#45808)
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
- UI table controls stay visible when empty. On Hosts, Reports, Policies, and Software pages, search bars, filters, dropdowns, remain visible but disabled when empty — avoids layout shift when the first item is added. Item count remains visible.
|
||||
- UI has action-oriented empty state copy. Headers describe current state ("No hosts", "No policies for this fleet") instead of prompting action. Body text explains what to expect. CTA buttons are explicit ("Add policy", "Schedule a report") and permission gated.
|
||||
- UI shows consistent page descriptions and learn more links (added to Settings. Fleets, Ticket destinations, Certificates, and Identity provider pages).
|
||||
@@ -64,9 +64,11 @@ describe("Custom variables", () => {
|
||||
"Add a custom variable to make it available in scripts and profiles."
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Add custom variable" })
|
||||
).toBeInTheDocument();
|
||||
// Header button and EmptyState CTA button both render
|
||||
const addButtons = screen.getAllByRole("button", {
|
||||
name: /Add custom variable/,
|
||||
});
|
||||
expect(addButtons).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -167,43 +167,19 @@ const Variables = () => {
|
||||
</>
|
||||
);
|
||||
|
||||
const renderPageDescription = () => (
|
||||
<PageDescription
|
||||
variant="tab-panel"
|
||||
content={
|
||||
<>
|
||||
{isPremiumTier
|
||||
? "Manage custom variables that will be available in scripts and profiles across all fleets."
|
||||
: "Manage custom variables that will be available in scripts and profiles."}{" "}
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url={`${FLEET_WEBSITE_URL}/guides/secrets-in-scripts-and-configuration-profiles`}
|
||||
newTab
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
const isEmpty = !isLoading && data?.count === 0;
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__page-header`}>
|
||||
{renderPageDescription()}
|
||||
</div>
|
||||
const renderContent = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={`${baseClass}__loading`}>
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (data?.count === 0) {
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__page-header`}>
|
||||
{renderPageDescription()}
|
||||
</div>
|
||||
if (isEmpty) {
|
||||
return (
|
||||
<EmptyState
|
||||
variant="header-list"
|
||||
header="No custom variables"
|
||||
@@ -227,36 +203,10 @@ const Variables = () => {
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
{showAddModal && (
|
||||
<AddCustomVariableModal
|
||||
onCancel={() => setShowAddModal(false)}
|
||||
onSave={onSaveVariable}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__page-header`}>
|
||||
{renderPageDescription()}
|
||||
{canEdit && (
|
||||
<GitOpsModeTooltipWrapper
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
variant="inverse"
|
||||
size="small"
|
||||
onClick={onClickAddVariable}
|
||||
disabled={disableChildren}
|
||||
>
|
||||
<Icon name="plus" />
|
||||
<span>Add custom variable</span>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
return (
|
||||
<PaginatedList<IVariable>
|
||||
ref={paginatedListRef}
|
||||
pageSize={VARIABLES_PAGE_SIZE}
|
||||
@@ -281,6 +231,44 @@ const Variables = () => {
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<div className={`${baseClass}__page-header`}>
|
||||
<PageDescription
|
||||
variant="tab-panel"
|
||||
content={
|
||||
<>
|
||||
{isPremiumTier
|
||||
? "Manage custom variables that will be available in scripts and profiles across all fleets."
|
||||
: "Manage custom variables that will be available in scripts and profiles."}{" "}
|
||||
<CustomLink
|
||||
text="Learn more"
|
||||
url={`${FLEET_WEBSITE_URL}/guides/secrets-in-scripts-and-configuration-profiles`}
|
||||
newTab
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{canEdit && (
|
||||
<GitOpsModeTooltipWrapper
|
||||
renderChildren={(disableChildren) => (
|
||||
<Button
|
||||
variant="inverse"
|
||||
size="small"
|
||||
onClick={onClickAddVariable}
|
||||
disabled={disableChildren}
|
||||
>
|
||||
<Icon name="plus" />
|
||||
<span>Add custom variable</span>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{renderContent()}
|
||||
{showAddModal && (
|
||||
<AddCustomVariableModal
|
||||
onCancel={() => setShowAddModal(false)}
|
||||
|
||||
@@ -165,12 +165,21 @@ const PolicyResults = ({
|
||||
}
|
||||
|
||||
if (finishedWithNoResults) {
|
||||
const hostVerb = targetsTotalCount === 1 ? "host is" : "hosts are";
|
||||
const errorsMessage = errors?.length ? (
|
||||
<>
|
||||
{" "}
|
||||
or review the <strong>Errors</strong> tab for details
|
||||
</>
|
||||
) : null;
|
||||
return (
|
||||
<EmptyState
|
||||
header="Your live report returned no results"
|
||||
info={`Expecting to see results? Check to see if the host${
|
||||
targetsTotalCount > 1 ? "s" : ""
|
||||
} you targeted reported "Online" or check out the "Errors" table.`}
|
||||
header="No results returned"
|
||||
info={
|
||||
<>
|
||||
Check whether the {hostVerb} online{errorsMessage}.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -156,12 +156,21 @@ const QueryResults = ({
|
||||
};
|
||||
|
||||
const renderNoResults = () => {
|
||||
const hostVerb = targetsTotalCount === 1 ? "host is" : "hosts are";
|
||||
const errorsMessage = errors?.length ? (
|
||||
<>
|
||||
{" "}
|
||||
or review the <strong>Errors</strong> tab for details
|
||||
</>
|
||||
) : null;
|
||||
return (
|
||||
<EmptyState
|
||||
header="Your live report returned no results"
|
||||
info={`Expecting to see results? Check to see if the host${
|
||||
targetsTotalCount > 1 ? "s" : ""
|
||||
} you targeted reported "Online" or check out the "Errors" table.`}
|
||||
header="No results returned"
|
||||
info={
|
||||
<>
|
||||
Check whether the {hostVerb} online{errorsMessage}.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user