mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
add permission to host page (#852)
* update genreating of available host table headers based on tier * stoping point for host permissions * fixed up available headers for teams depending on permissions * show select column on host table properly
This commit is contained in:
parent
a2a7082bd3
commit
d3932d736d
3 changed files with 84 additions and 15 deletions
|
|
@ -17,7 +17,10 @@ import {
|
|||
humanHostLastSeen,
|
||||
humanHostDetailUpdated,
|
||||
} from "kolide/helpers";
|
||||
import PATHS from "../../../router/paths";
|
||||
import { IConfig } from "interfaces/config";
|
||||
import { IUser } from "interfaces/user";
|
||||
import PATHS from "router/paths";
|
||||
import permissionUtils from "utilities/permissions";
|
||||
|
||||
interface IHeaderProps {
|
||||
column: {
|
||||
|
|
@ -56,7 +59,7 @@ const lastSeenTime = (status: string, seenTime: string): string => {
|
|||
return "Online";
|
||||
};
|
||||
|
||||
const hostTableHeaders: IHostDataColumn[] = [
|
||||
const allHostTableHeaders: IHostDataColumn[] = [
|
||||
// We are using React Table useRowSelect functionality for the selection header.
|
||||
// More information on its API can be found here
|
||||
// https://react-table.tanstack.com/docs/api/useRowSelect
|
||||
|
|
@ -102,6 +105,12 @@ const hostTableHeaders: IHostDataColumn[] = [
|
|||
),
|
||||
disableHidden: true,
|
||||
},
|
||||
{
|
||||
title: "Team",
|
||||
Header: "Team",
|
||||
accessor: "team_name",
|
||||
Cell: (cellProps) => <TextCell value={cellProps.cell.value} />,
|
||||
},
|
||||
{
|
||||
title: "Status",
|
||||
Header: "Status",
|
||||
|
|
@ -261,12 +270,58 @@ const defaultHiddenColumns = [
|
|||
"hardware_serial",
|
||||
];
|
||||
|
||||
const generateVisibleHostColumns = (
|
||||
hiddenColumns: string[]
|
||||
/**
|
||||
* Will generate a host table column configuration based off of the current user
|
||||
* permissions and license tier of fleet they are on.
|
||||
*/
|
||||
const generateAvailableTableHeaders = (
|
||||
config: IConfig,
|
||||
currentUser: IUser
|
||||
): IHostDataColumn[] => {
|
||||
return hostTableHeaders.filter((column) => {
|
||||
return allHostTableHeaders.reduce(
|
||||
(columns: IHostDataColumn[], currentColumn: IHostDataColumn) => {
|
||||
// skip over column headers that are not shown in core tier
|
||||
if (permissionUtils.isCoreTier(config)) {
|
||||
if (
|
||||
currentColumn.accessor === "team_name" ||
|
||||
currentColumn.id === "selection"
|
||||
) {
|
||||
return columns;
|
||||
}
|
||||
// In base tier, we want to check user role to enable/disable select column
|
||||
} else if (
|
||||
!permissionUtils.isGlobalAdmin(currentUser) &&
|
||||
!permissionUtils.isGlobalMaintainer(currentUser)
|
||||
) {
|
||||
if (currentColumn.id === "selection") {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
|
||||
columns.push(currentColumn);
|
||||
return columns;
|
||||
},
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Will generate a host table column configuration that a user currently sees.
|
||||
*
|
||||
*/
|
||||
const generateVisibleTableColumns = (
|
||||
hiddenColumns: string[],
|
||||
config: IConfig,
|
||||
currentUser: IUser
|
||||
): IHostDataColumn[] => {
|
||||
// remove columns set as hidden by the user.
|
||||
return generateAvailableTableHeaders(config, currentUser).filter((column) => {
|
||||
return !hiddenColumns.includes(column.accessor as string);
|
||||
});
|
||||
};
|
||||
|
||||
export { hostTableHeaders, defaultHiddenColumns, generateVisibleHostColumns };
|
||||
export {
|
||||
defaultHiddenColumns,
|
||||
generateAvailableTableHeaders,
|
||||
generateVisibleTableColumns,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import TableContainer from "components/TableContainer";
|
|||
import labelInterface from "interfaces/label";
|
||||
import hostInterface from "interfaces/host";
|
||||
import teamInterface from "interfaces/team";
|
||||
import userInterface from "interfaces/user";
|
||||
import osqueryTableInterface from "interfaces/osquery_table";
|
||||
import statusLabelsInterface from "interfaces/status_labels";
|
||||
import enrollSecretInterface from "interfaces/enroll_secret";
|
||||
|
|
@ -33,8 +34,8 @@ import deepDifference from "utilities/deep_difference";
|
|||
import permissionUtils from "utilities/permissions";
|
||||
import {
|
||||
defaultHiddenColumns,
|
||||
hostTableHeaders,
|
||||
generateVisibleHostColumns,
|
||||
generateVisibleTableColumns,
|
||||
generateAvailableTableHeaders,
|
||||
} from "./HostTableConfig";
|
||||
import AddHostModal from "./components/AddHostModal";
|
||||
import NoHosts from "./components/NoHosts";
|
||||
|
|
@ -69,6 +70,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
canAddNewHosts: PropTypes.bool,
|
||||
teams: PropTypes.arrayOf(teamInterface),
|
||||
isGlobalAdmin: PropTypes.bool,
|
||||
currentUser: userInterface,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -168,7 +170,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
};
|
||||
|
||||
// NOTE: this is called once on the initial rendering. The initial render of
|
||||
// the TableContainer child component.
|
||||
// the TableContainer child component will call this handler.
|
||||
onTableQueryChange = (queryData) => {
|
||||
const { selectedFilter, dispatch } = this.props;
|
||||
const {
|
||||
|
|
@ -260,7 +262,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
"success",
|
||||
`Hosts successfully transferred to ${team.name}.`
|
||||
)
|
||||
); // TODO: update team name
|
||||
);
|
||||
})
|
||||
.catch(() => {
|
||||
dispatch(
|
||||
|
|
@ -294,6 +296,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
};
|
||||
|
||||
renderEditColumnsModal = () => {
|
||||
const { config, currentUser } = this.props;
|
||||
const { showEditColumnsModal, hiddenColumns } = this.state;
|
||||
|
||||
if (!showEditColumnsModal) return null;
|
||||
|
|
@ -305,7 +308,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
className={`${baseClass}__invite-modal`}
|
||||
>
|
||||
<EditColumnsModal
|
||||
columns={hostTableHeaders}
|
||||
columns={generateAvailableTableHeaders(config, currentUser)}
|
||||
hiddenColumns={hiddenColumns}
|
||||
onSaveColumns={this.onSaveColumns}
|
||||
onCancelColumns={this.onCancelColumns}
|
||||
|
|
@ -548,7 +551,14 @@ export class ManageHostsPage extends PureComponent {
|
|||
};
|
||||
|
||||
renderTable = () => {
|
||||
const { selectedFilter, selectedLabel, hosts, loadingHosts } = this.props;
|
||||
const {
|
||||
config,
|
||||
currentUser,
|
||||
selectedFilter,
|
||||
selectedLabel,
|
||||
hosts,
|
||||
loadingHosts,
|
||||
} = this.props;
|
||||
const { hiddenColumns } = this.state;
|
||||
const {
|
||||
onTableQueryChange,
|
||||
|
|
@ -567,7 +577,11 @@ export class ManageHostsPage extends PureComponent {
|
|||
|
||||
return (
|
||||
<TableContainer
|
||||
columns={generateVisibleHostColumns(hiddenColumns)}
|
||||
columns={generateVisibleTableColumns(
|
||||
hiddenColumns,
|
||||
config,
|
||||
currentUser
|
||||
)}
|
||||
data={hosts}
|
||||
isLoading={loadingHosts}
|
||||
defaultSortHeader={"hostname"}
|
||||
|
|
@ -667,7 +681,6 @@ const mapStateToProps = (state, { location, params }) => {
|
|||
permissionUtils.isGlobalAdmin(currentUser) ||
|
||||
permissionUtils.isGlobalMaintainer(currentUser);
|
||||
const isGlobalAdmin = permissionUtils.isGlobalAdmin(currentUser);
|
||||
|
||||
const teams = memoizedGetEntity(state.entities.teams.data);
|
||||
|
||||
return {
|
||||
|
|
@ -682,6 +695,7 @@ const mapStateToProps = (state, { location, params }) => {
|
|||
selectedOsqueryTable,
|
||||
statusLabels,
|
||||
config,
|
||||
currentUser,
|
||||
hosts,
|
||||
loadingHosts,
|
||||
canAddNewHosts,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { IUser } from "interfaces/user";
|
||||
import { IConfig } from "../../interfaces/config";
|
||||
import { IConfig } from "interfaces/config";
|
||||
|
||||
const isCoreTier = (config: IConfig): boolean => {
|
||||
return config.tier === "core";
|
||||
|
|
|
|||
Loading…
Reference in a new issue