mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
App wide UI: Fix policies keys (#3145)
This commit is contained in:
parent
b3b107512e
commit
3b0a454fb5
14 changed files with 66 additions and 47 deletions
1
changes/issue-3112-policies-key-update-app-wide
Normal file
1
changes/issue-3112-policies-key-update-app-wide
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Frontend and UI use new policies API keys appwide
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import PropTypes from "prop-types";
|
||||
import hostPolicyInterface, { IHostPolicy } from "./host_policy";
|
||||
import hostPolicyInterface, { IHostPolicy } from "./policy";
|
||||
import hostUserInterface, { IHostUser } from "./host_users";
|
||||
import labelInterface, { ILabel } from "./label";
|
||||
import packInterface, { IPack } from "./pack";
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
import PropTypes from "prop-types";
|
||||
|
||||
export default PropTypes.shape({
|
||||
id: PropTypes.number.isRequired,
|
||||
query_id: PropTypes.number,
|
||||
query_name: PropTypes.string.isRequired,
|
||||
query_description: PropTypes.string,
|
||||
response: PropTypes.string,
|
||||
resolution: PropTypes.string,
|
||||
});
|
||||
|
||||
export interface IHostPolicy {
|
||||
id: number;
|
||||
query_id: number;
|
||||
query_name: string;
|
||||
query_description?: string;
|
||||
response: string;
|
||||
resolution?: string;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import PropTypes, { string } from "prop-types";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default PropTypes.shape({
|
||||
online_count: PropTypes.number,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,21 @@
|
|||
import PropTypes from "prop-types";
|
||||
|
||||
// Legacy PropTypes used on host interface
|
||||
export default PropTypes.shape({
|
||||
author_email: PropTypes.string.isRequired,
|
||||
author_id: PropTypes.number.isRequired,
|
||||
author_name: PropTypes.string.isRequired,
|
||||
created_at: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
id: PropTypes.number.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
query: PropTypes.string.isRequired,
|
||||
resoluton: PropTypes.string.isRequired,
|
||||
response: PropTypes.string,
|
||||
team_id: PropTypes.number,
|
||||
updated_at: PropTypes.string.isRequired,
|
||||
});
|
||||
|
||||
export interface IPolicy {
|
||||
id: number;
|
||||
name: string;
|
||||
|
|
@ -7,9 +25,20 @@ export interface IPolicy {
|
|||
author_name: string;
|
||||
author_email: string;
|
||||
resolution: string;
|
||||
team_id?: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
// Used on the manage hosts page and other places where aggregate stats are displayed
|
||||
export interface IPolicyStats extends IPolicy {
|
||||
passing_host_count: number;
|
||||
failing_host_count: number;
|
||||
team_id?: number;
|
||||
}
|
||||
|
||||
// Used on the host details page and other places where the status of individual hosts are displayed
|
||||
export interface IHostPolicy extends IPolicy {
|
||||
response: string;
|
||||
}
|
||||
|
||||
export interface IPolicyFormData {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { useDispatch } from "react-redux";
|
|||
import moment from "moment";
|
||||
|
||||
import { IHost } from "interfaces/host";
|
||||
import { IHostPolicy } from "interfaces/host_policy";
|
||||
import { IHostPolicy } from "interfaces/policy";
|
||||
import hostAPI from "services/entities/hosts"; // @ts-ignore
|
||||
import { renderFlash } from "redux/nodes/notifications/actions";
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ const WelcomeHost = (): JSX.Element => {
|
|||
alt={p.response}
|
||||
src={p.response === policyPass ? IconPassed : IconError}
|
||||
/>
|
||||
{p.query_name}
|
||||
{p.name}
|
||||
</div>
|
||||
<Button
|
||||
variant="text-icon"
|
||||
|
|
@ -275,12 +275,12 @@ const WelcomeHost = (): JSX.Element => {
|
|||
</div>
|
||||
{showPolicyModal && (
|
||||
<Modal
|
||||
title={currentPolicyShown?.query_name || ""}
|
||||
title={currentPolicyShown?.name || ""}
|
||||
onExit={() => setShowPolicyModal(false)}
|
||||
className={`${baseClass}__policy-modal`}
|
||||
>
|
||||
<>
|
||||
<p>{currentPolicyShown?.query_description}</p>
|
||||
<p>{currentPolicyShown?.description}</p>
|
||||
{currentPolicyShown?.resolution && (
|
||||
<p>
|
||||
<b>Resolve:</b> {currentPolicyShown.resolution}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import { PolicyContext } from "context/policy";
|
|||
import { IHost, IPackStats } from "interfaces/host";
|
||||
import { IQueryStats } from "interfaces/query_stats";
|
||||
import { ISoftware } from "interfaces/software";
|
||||
import { IHostPolicy } from "interfaces/host_policy";
|
||||
import { IHostPolicy } from "interfaces/policy";
|
||||
import { ILabel } from "interfaces/label";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import { IQuery } from "interfaces/query";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Link } from "react-router";
|
|||
import PATHS from "router/paths";
|
||||
import StatusCell from "components/TableContainer/DataTable/StatusCell";
|
||||
import Button from "components/buttons/Button";
|
||||
import { IHostPolicy } from "interfaces/host_policy";
|
||||
import { IHostPolicy } from "interfaces/policy";
|
||||
import { PolicyResponse } from "utilities/constants";
|
||||
|
||||
import Chevron from "../../../../../assets/images/icon-chevron-right-9x6@2x.png";
|
||||
|
|
@ -61,7 +61,7 @@ const generatePolicyTableHeaders = (
|
|||
accessor: "name",
|
||||
disableSortBy: true,
|
||||
Cell: (cellProps) => {
|
||||
const { query_name } = cellProps.row.original;
|
||||
const { name } = cellProps.row.original;
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
|
|
@ -71,7 +71,7 @@ const generatePolicyTableHeaders = (
|
|||
variant={"text-icon"}
|
||||
>
|
||||
<>
|
||||
{query_name}
|
||||
{name}
|
||||
<img src={ArrowIcon} alt="View policy details" />
|
||||
</>
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import Button from "components/buttons/Button";
|
||||
import Modal from "components/Modal";
|
||||
|
||||
import { IHostPolicy } from "interfaces/host_policy";
|
||||
import { IHostPolicy } from "interfaces/policy";
|
||||
|
||||
interface IPolicyDetailsProps {
|
||||
onCancel: () => void;
|
||||
|
|
@ -17,12 +17,12 @@ const PolicyDetailsModal = ({
|
|||
}: IPolicyDetailsProps): JSX.Element => {
|
||||
return (
|
||||
<Modal
|
||||
title={`${policy?.query_name || "Query name"}`}
|
||||
title={`${policy?.name || "Policy name"}`}
|
||||
onExit={onCancel}
|
||||
className={baseClass}
|
||||
>
|
||||
<div className={`${baseClass}__modal-body`}>
|
||||
<p>{policy?.query_description}</p>
|
||||
<p>{policy?.description}</p>
|
||||
{policy?.resolution && (
|
||||
<div className={`${baseClass}__resolution`}>
|
||||
<span className={`${baseClass}__resolve-header`}> Resolve:</span>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { IHostPolicy } from "interfaces/host_policy";
|
||||
import { IHostPolicy } from "interfaces/policy";
|
||||
import React from "react";
|
||||
|
||||
import IssueIcon from "../../../../../../assets/images/icon-issue-fleet-black-50-16x16@2x.png";
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { renderFlash } from "redux/nodes/notifications/actions";
|
|||
|
||||
import PATHS from "router/paths";
|
||||
|
||||
import { IPolicy } from "interfaces/policy";
|
||||
import { IPolicy, IPolicyStats } from "interfaces/policy";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import { IUser } from "interfaces/user";
|
||||
|
||||
|
|
@ -99,10 +99,14 @@ const ManagePolicyPage = (managePoliciesPageProps: {
|
|||
);
|
||||
|
||||
// ===== local state
|
||||
const [globalPolicies, setGlobalPolicies] = useState<IPolicy[] | never[]>([]);
|
||||
const [globalPolicies, setGlobalPolicies] = useState<
|
||||
IPolicyStats[] | never[]
|
||||
>([]);
|
||||
const [isLoadingGlobalPolicies, setIsLoadingGlobalPolicies] = useState(true);
|
||||
const [isGlobalPoliciesError, setIsGlobalPoliciesError] = useState(false);
|
||||
const [teamPolicies, setTeamPolicies] = useState<IPolicy[] | never[]>([]);
|
||||
const [teamPolicies, setTeamPolicies] = useState<IPolicyStats[] | never[]>(
|
||||
[]
|
||||
);
|
||||
const [isLoadingTeamPolicies, setIsLoadingTeamPolicies] = useState(true);
|
||||
const [isTeamPoliciesError, setIsTeamPoliciesError] = useState(false);
|
||||
const [userTeams, setUserTeams] = useState<ITeam[] | never[] | null>(null);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { noop } from "lodash";
|
|||
import paths from "router/paths";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
import { IPolicy } from "interfaces/policy";
|
||||
import { IPolicyStats } from "interfaces/policy";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import TableContainer from "components/TableContainer";
|
||||
import { generateTableHeaders, generateDataSet } from "./PoliciesTableConfig";
|
||||
|
|
@ -20,7 +20,7 @@ const TAGGED_TEMPLATES = {
|
|||
};
|
||||
|
||||
interface IPoliciesListWrapperProps {
|
||||
policiesList: IPolicy[];
|
||||
policiesList: IPolicyStats[];
|
||||
isLoading: boolean;
|
||||
onRemovePoliciesClick: (selectedTableIds: number[]) => void;
|
||||
resultsTitle?: string;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { memoize } from "lodash";
|
|||
import Checkbox from "components/forms/fields/Checkbox";
|
||||
import LinkCell from "components/TableContainer/DataTable/LinkCell/LinkCell";
|
||||
import TextCell from "components/TableContainer/DataTable/TextCell";
|
||||
import { IPolicy } from "interfaces/policy";
|
||||
import { IPolicyStats } from "interfaces/policy";
|
||||
import PATHS from "router/paths";
|
||||
import sortUtils from "utilities/sort";
|
||||
import { PolicyResponse } from "utilities/constants";
|
||||
|
|
@ -42,7 +42,7 @@ interface ICellProps {
|
|||
value: any;
|
||||
};
|
||||
row: {
|
||||
original: IPolicy;
|
||||
original: IPolicyStats;
|
||||
getToggleRowSelectedProps: () => any; // TODO: do better with types
|
||||
toggleRowSelected: () => void;
|
||||
};
|
||||
|
|
@ -175,11 +175,13 @@ const generateTableHeaders = (options: {
|
|||
}
|
||||
};
|
||||
|
||||
const generateDataSet = memoize((policiesList: IPolicy[] = []): IPolicy[] => {
|
||||
policiesList = policiesList.sort((a, b) =>
|
||||
sortUtils.caseInsensitiveAsc(a.name, b.name)
|
||||
);
|
||||
return policiesList;
|
||||
});
|
||||
const generateDataSet = memoize(
|
||||
(policiesList: IPolicyStats[] = []): IPolicyStats[] => {
|
||||
policiesList = policiesList.sort((a, b) =>
|
||||
sortUtils.caseInsensitiveAsc(a.name, b.name)
|
||||
);
|
||||
return policiesList;
|
||||
}
|
||||
);
|
||||
|
||||
export { generateTableHeaders, generateDataSet };
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ export const DEFAULT_POLICY = {
|
|||
resolution: "Resolution steps",
|
||||
passing_host_count: 2000,
|
||||
failing_host_count: 300,
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
};
|
||||
|
||||
export const DEFAULT_CAMPAIGN = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue