mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Spiffier UI: Fix empty states (#5395)
This commit is contained in:
parent
390ea4d82f
commit
0aa8db3a2f
8 changed files with 80 additions and 38 deletions
1
changes/issue-5315-consistent-empty-states
Normal file
1
changes/issue-5315-consistent-empty-states
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Fix policies empty state to match other empty states, fix link styling
|
||||
|
|
@ -15,9 +15,11 @@ describe("Policies flow (empty)", () => {
|
|||
cy.visit("/policies/manage");
|
||||
});
|
||||
it("creates a custom policy", () => {
|
||||
cy.getAttached(".manage-policies-page__header-wrap").within(() => {
|
||||
cy.findByText(/add a policy/i).click();
|
||||
});
|
||||
cy.getAttached(".policies-list-wrapper__action-button-container").within(
|
||||
() => {
|
||||
cy.findByText(/add a policy/i).click();
|
||||
}
|
||||
);
|
||||
cy.findByText(/create your own policy/i).click();
|
||||
cy.getAttached(".ace_scroller")
|
||||
.click({ force: true })
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ describe("Premium tier - Global Admin user", () => {
|
|||
describe("Manage policies page", () => {
|
||||
beforeEach(() => cy.visit("/policies/manage"));
|
||||
it("allows global admin to add a new policy", () => {
|
||||
cy.getAttached(".button-wrap")
|
||||
cy.getAttached(".policies-list-wrapper__action-button-container")
|
||||
.findByRole("button", { name: /add a policy/i })
|
||||
.click();
|
||||
// Add a default policy
|
||||
|
|
|
|||
|
|
@ -230,8 +230,8 @@ describe("Premium tier - Maintainer user", () => {
|
|||
cy.findByText(/manage hosts/i).should("not.exist");
|
||||
});
|
||||
it("allows global maintainer to add a new policy", () => {
|
||||
cy.getAttached(".button-wrap")
|
||||
.findByRole("button", { name: /add a polic/i })
|
||||
cy.getAttached(".policies-list-wrapper__action-button-container")
|
||||
.findByRole("button", { name: /add a policy/i })
|
||||
.click();
|
||||
// Add a default policy
|
||||
cy.findByText(/gatekeeper enabled/i).click();
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@ const ManagePolicyPage = ({
|
|||
}
|
||||
}, [availableTeams]);
|
||||
|
||||
const showCtaButtons =
|
||||
(!!teamId && teamPolicies) || (!teamId && globalPolicies);
|
||||
|
||||
return !availableTeams ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
|
|
@ -356,30 +359,32 @@ const ManagePolicyPage = ({
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`${baseClass} button-wrap`}>
|
||||
{canManageAutomations &&
|
||||
!isLoadingWebhooks &&
|
||||
!isLoadingGlobalPolicies && (
|
||||
<Button
|
||||
onClick={toggleManageAutomationsModal}
|
||||
className={`${baseClass}__manage-automations button`}
|
||||
variant="inverse"
|
||||
>
|
||||
<span>Manage automations</span>
|
||||
</Button>
|
||||
{showCtaButtons && (
|
||||
<div className={`${baseClass} button-wrap`}>
|
||||
{canManageAutomations &&
|
||||
!isLoadingWebhooks &&
|
||||
!isLoadingGlobalPolicies && (
|
||||
<Button
|
||||
onClick={toggleManageAutomationsModal}
|
||||
className={`${baseClass}__manage-automations button`}
|
||||
variant="inverse"
|
||||
>
|
||||
<span>Manage automations</span>
|
||||
</Button>
|
||||
)}
|
||||
{canAddOrRemovePolicy && (
|
||||
<div className={`${baseClass}__action-button-container`}>
|
||||
<Button
|
||||
variant="brand"
|
||||
className={`${baseClass}__select-policy-button`}
|
||||
onClick={onAddPolicyClick}
|
||||
>
|
||||
Add a policy
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{canAddOrRemovePolicy && (
|
||||
<div className={`${baseClass}__action-button-container`}>
|
||||
<Button
|
||||
variant="brand"
|
||||
className={`${baseClass}__select-policy-button`}
|
||||
onClick={onAddPolicyClick}
|
||||
>
|
||||
Add a policy
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={`${baseClass}__description`}>
|
||||
{showTeamDescription ? (
|
||||
|
|
@ -404,6 +409,7 @@ const ManagePolicyPage = ({
|
|||
<PoliciesListWrapper
|
||||
policiesList={teamPolicies || []}
|
||||
isLoading={isLoadingTeamPolicies && isLoadingWebhooks}
|
||||
onAddPolicyClick={onAddPolicyClick}
|
||||
onRemovePoliciesClick={onRemovePoliciesClick}
|
||||
canAddOrRemovePolicy={canAddOrRemovePolicy}
|
||||
currentTeam={currentTeam}
|
||||
|
|
@ -419,6 +425,7 @@ const ManagePolicyPage = ({
|
|||
<PoliciesListWrapper
|
||||
policiesList={globalPolicies || []}
|
||||
isLoading={isLoadingGlobalPolicies && isLoadingWebhooks}
|
||||
onAddPolicyClick={onAddPolicyClick}
|
||||
onRemovePoliciesClick={onRemovePoliciesClick}
|
||||
canAddOrRemovePolicy={canAddOrRemovePolicy}
|
||||
currentTeam={currentTeam}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import paths from "router/paths";
|
|||
|
||||
import { IPolicyStats } from "interfaces/policy";
|
||||
import { ITeamSummary } from "interfaces/team";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
import Spinner from "components/Spinner";
|
||||
import TableContainer from "components/TableContainer";
|
||||
import { generateTableHeaders, generateDataSet } from "./PoliciesTableConfig";
|
||||
|
|
@ -22,6 +24,7 @@ const TAGGED_TEMPLATES = {
|
|||
interface IPoliciesListWrapperProps {
|
||||
policiesList: IPolicyStats[];
|
||||
isLoading: boolean;
|
||||
onAddPolicyClick?: () => void;
|
||||
onRemovePoliciesClick: (selectedTableIds: number[]) => void;
|
||||
resultsTitle?: string;
|
||||
canAddOrRemovePolicy?: boolean;
|
||||
|
|
@ -33,6 +36,7 @@ interface IPoliciesListWrapperProps {
|
|||
const PoliciesListWrapper = ({
|
||||
policiesList,
|
||||
isLoading,
|
||||
onAddPolicyClick,
|
||||
onRemovePoliciesClick,
|
||||
resultsTitle,
|
||||
canAddOrRemovePolicy,
|
||||
|
|
@ -85,6 +89,17 @@ const PoliciesListWrapper = ({
|
|||
changes.
|
||||
</p>
|
||||
</div>
|
||||
{canAddOrRemovePolicy && (
|
||||
<div className={`${baseClass}__action-button-container`}>
|
||||
<Button
|
||||
variant="brand"
|
||||
className={`${baseClass}__select-policy-button`}
|
||||
onClick={onAddPolicyClick}
|
||||
>
|
||||
Add a policy
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,16 @@
|
|||
.manage-queries-page {
|
||||
a {
|
||||
font-size: $x-small;
|
||||
color: $core-vibrant-blue;
|
||||
font-weight: $bold;
|
||||
text-decoration: none;
|
||||
|
||||
img {
|
||||
transform: scale(0.5);
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
&__header-wrap {
|
||||
height: 38px;
|
||||
display: flex;
|
||||
|
|
@ -246,11 +258,6 @@
|
|||
margin-bottom: $pad-medium;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 176px;
|
||||
margin-right: $pad-xlarge;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $core-fleet-black;
|
||||
font-weight: $regular;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import Button from "components/buttons/Button";
|
|||
import TableContainer from "components/TableContainer";
|
||||
import generateTableHeaders from "./QueriesTableConfig";
|
||||
|
||||
import OpenNewTabIcon from "../../../../../../assets/images/open-new-tab-12x12@2x.png";
|
||||
|
||||
const baseClass = "queries-list-wrapper";
|
||||
const noQueriesClass = "no-queries";
|
||||
interface IQueryTableData extends IQuery {
|
||||
|
|
@ -65,11 +67,19 @@ const QueriesListWrapper = ({
|
|||
{!isOnlyObserver && (
|
||||
<>
|
||||
<p>
|
||||
Create a new query, or go to GitHub to{" "}
|
||||
<a href="https://fleetdm.com/docs/using-fleet/standard-query-library">
|
||||
import Fleet’s standard query library
|
||||
Create a new query, or{" "}
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href="https://fleetdm.com/docs/using-fleet/standard-query-library"
|
||||
>
|
||||
import Fleet’s standard query library{" "}
|
||||
<img
|
||||
src={OpenNewTabIcon}
|
||||
alt="open new tab"
|
||||
id="new-tab-icon"
|
||||
/>
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<Button
|
||||
variant="brand"
|
||||
|
|
|
|||
Loading…
Reference in a new issue