UI: Clean up various states on the Settings page (#28752)

## For #28266 

<img width="1912" alt="Screenshot 2025-05-01 at 9 48 06 PM"
src="https://github.com/user-attachments/assets/f8b66d86-79c5-4166-b328-4befc3bd51f9"
/>
<img width="1912" alt="Screenshot 2025-05-01 at 9 48 44 PM"
src="https://github.com/user-attachments/assets/c7ddf782-4cfe-45a3-b291-86a61d127264"
/>
<img width="1912" alt="Screenshot 2025-05-01 at 9 49 43 PM"
src="https://github.com/user-attachments/assets/354ccdb6-f7f9-41c6-aceb-b08d2c8b76f0"
/>
<img width="1912" alt="Screenshot 2025-05-01 at 9 51 42 PM"
src="https://github.com/user-attachments/assets/d9405f9b-1146-47ea-a18c-8047cbfecffd"
/>

- [x] Changes file added for user-visible changes in `changes/`
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
jacobshandling 2025-05-02 09:14:30 -07:00 committed by GitHub
parent 57a2fb4341
commit dc490c236d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 77 additions and 41 deletions

View file

@ -0,0 +1 @@
* Clean up various empty and configured states on the settings pages

View file

@ -17,6 +17,7 @@ import configAPI from "services/entities/config";
import TableContainer from "components/TableContainer";
import TableDataError from "components/DataError";
import SectionHeader from "components/SectionHeader";
import Spinner from "components/Spinner";
import AddIntegrationModal from "./components/AddIntegrationModal";
import DeleteIntegrationModal from "./components/DeleteIntegrationModal";
@ -267,6 +268,41 @@ const Integrations = (): JSX.Element => {
[jiraIntegrations, zendeskIntegrations]
);
const renderTable = () => {
if (loadingIntegrationsError) {
return <TableDataError />;
}
if (isLoadingIntegrations) {
return <Spinner />;
}
return (
<TableContainer
columnConfigs={tableHeaders}
data={tableData}
defaultSortHeader="name"
defaultSortDirection="asc"
isLoading={false}
actionButton={{
name: "add integration",
buttonText: "Add integration",
variant: "default",
onClick: toggleAddIntegrationModal,
hideButton: !tableData?.length,
}}
resultsTitle="integrations"
emptyComponent={() => (
<EmptyIntegrationsTable
className={noIntegrationsClass}
onActionButtonClick={toggleAddIntegrationModal}
/>
)}
showMarkAllPages={false}
isAllPagesSelected={false}
disablePagination
/>
);
};
return (
<div className={`${baseClass}`}>
<SectionHeader title="Ticket destinations" />
@ -274,34 +310,7 @@ const Integrations = (): JSX.Element => {
Add or edit integrations to create tickets when Fleet detects new
vulnerabilities.
</p>
{loadingIntegrationsError ? (
<TableDataError />
) : (
<TableContainer
columnConfigs={tableHeaders}
data={tableData}
isLoading={isLoadingIntegrations}
defaultSortHeader="name"
defaultSortDirection="asc"
actionButton={{
name: "add integration",
buttonText: "Add integration",
variant: "default",
onClick: toggleAddIntegrationModal,
hideButton: !tableData?.length,
}}
resultsTitle="integrations"
emptyComponent={() => (
<EmptyIntegrationsTable
className={noIntegrationsClass}
onActionButtonClick={toggleAddIntegrationModal}
/>
)}
showMarkAllPages={false}
isAllPagesSelected={false}
disablePagination
/>
)}
{renderTable()}
{showAddIntegrationModal && (
<AddIntegrationModal
onCancel={toggleAddIntegrationModal}

View file

@ -75,6 +75,26 @@
width: calc(90% - 50px);
margin-bottom: $pad-medium;
}
&__ses-enabled {
display: flex;
flex-direction: column;
align-items: center;
gap: $pad-medium;
&__content {
text-align: center;
p {
margin: 0;
}
}
&__title {
font-size: $small;
font-weight: $bold;
margin-bottom: $pad-small;
}
}
}
}

View file

@ -12,10 +12,10 @@ import Dropdown from "components/forms/fields/Dropdown";
import InputField from "components/forms/fields/InputField";
// @ts-ignore
import validEmail from "components/forms/validators/valid_email";
import EmptyTable from "components/EmptyTable";
import CustomLink from "components/CustomLink";
import SectionHeader from "components/SectionHeader";
import GitOpsModeTooltipWrapper from "components/GitOpsModeTooltipWrapper";
import Card from "components/Card";
import {
IAppConfigFormProps,
@ -222,18 +222,24 @@ const Smtp = ({
};
const renderSesEnabled = () => {
const header = "Email already configured";
const info = (
<>
To configure SMTP,{" "}
<CustomLink
url={isPremiumTier ? CONTACT_FLEET_LINK : "https://fleetdm.com/slack"}
text="get help"
newTab
/>
</>
const sesBaseClass = `${baseClass}__ses-enabled`;
return (
<Card paddingSize="xxlarge" className={sesBaseClass}>
<div className={`${sesBaseClass}__content`}>
<p className={`${sesBaseClass}__title`}>Email already configured</p>
<p>
To configure SMTP,{" "}
<CustomLink
url={
isPremiumTier ? CONTACT_FLEET_LINK : "https://fleetdm.com/slack"
}
text="get help"
newTab
/>
</p>
</div>
</Card>
);
return <EmptyTable header={header} info={info} />;
};
const renderSmtpForm = () => {

View file

@ -30,7 +30,7 @@
.side-nav__card-container {
// all side navs in the admin section we want to limit the max width
> * {
> *:not(.loading-spinner) {
width: 100%;
max-width: $settings-form-max-width;
}