Skip to content

Commit

Permalink
Allow edit groups from an agent (#6250)
Browse files Browse the repository at this point in the history
* Agent groups column refactor and allow remove

* Agent groups allow edit

* Edit agent groups modal

* Fix links las registered agent

* Agent table with actions

* Extend funtionality from button with permissions and restore groups trucate component

* Modularize agents table actions

* Fix table filters

* Add form modal message

* Add CHANGELOG

* Update snapshot

* Fix return

* Fix actions field

* Fix snapshot

* Disable 'View details' actions when agent never connected

* Delete 'Upgrade' action
  • Loading branch information
lucianogorza authored Dec 28, 2023
1 parent ff561c5 commit e649ae2
Show file tree
Hide file tree
Showing 26 changed files with 1,032 additions and 760 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Added AngularJS dependencies [#6145](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6145)
- Remove embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120)
- Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227)
- Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250)

## Wazuh v4.8.1 - OpenSearch Dashboards 2.10.0 - Revision 00

Expand Down
115 changes: 50 additions & 65 deletions plugins/main/public/components/common/permissions/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,83 +10,68 @@
* Find more information about this on the LICENSE file.
*/

import React, { Fragment } from 'react';
import { useUserPermissionsRequirements } from '../hooks/useUserPermissions';
import { useUserRolesRequirements } from '../hooks/useUserRoles';
import React from 'react';

import {
EuiSwitch,
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
EuiLink,
EuiToolTip,
EuiSpacer
} from '@elastic/eui';

import { WzPermissionsFormatted } from './format';
import { IWzElementPermissionsProps, WzElementPermissions } from './element';

export interface IUserPermissionsObject{action: string, resource: string};
export type TUserPermissionsFunction = (props : any) => TUserPermissions;
export type TUserPermissions = (string | IUserPermissionsObject)[] | null;
export type TUserRoles = string[] | null;
export type TUserRolesFunction = (props : any) => TUserRoles;
interface IWzButtonPermissionsProps
extends Omit<
IWzElementPermissionsProps,
'children' | 'additionalPropsFunction'
> {
buttonType?: 'default' | 'empty' | 'icon' | 'link' | 'switch';
rest: any;
}

interface IWzButtonPermissionsProps{
permissions?: TUserPermissions | TUserPermissionsFunction
roles?: TUserRoles | TUserRolesFunction
buttonType?: 'default' | 'empty' | 'icon' | 'link' | 'switch'
tooltip?: any
rest?: any
};

export const WzButtonPermissions = ({permissions = null, roles = null, buttonType = 'default', tooltip, ...rest} : IWzButtonPermissionsProps) => {
const [userPermissionRequirements, userPermissions] = useUserPermissionsRequirements(typeof permissions === 'function' ? permissions(rest) : permissions);
const [userRolesRequirements, userRoles] = useUserRolesRequirements(typeof roles === 'function' ? roles(rest) : roles);
export const WzButtonPermissions = ({
buttonType = 'default',
permissions,
roles,
tooltip,
...rest
}: IWzButtonPermissionsProps) => {
const Button =
buttonType === 'empty'
? EuiButtonEmpty
: buttonType === 'icon'
? EuiButtonIcon
: buttonType === 'link'
? EuiLink
: buttonType === 'switch'
? EuiSwitch
: EuiButton;

const Button = buttonType === 'default' ? EuiButton
: buttonType === 'empty' ? EuiButtonEmpty
: buttonType === 'icon' ? EuiButtonIcon
: buttonType === 'link' ? EuiLink
: buttonType === 'switch' ? EuiSwitch
: null
const disabled = Boolean(userRolesRequirements || userPermissionRequirements || rest.isDisabled || rest.disabled);
const disabledProp = !['link', 'switch'].includes(buttonType) ? { isDisabled: disabled } : { disabled };
const onClick = disabled || !rest.onClick ? undefined : rest.onClick;
const onChange = disabled || !rest.onChange ? undefined : rest.onChange;
const customProps = { ...rest, onChange, onClick };
return (
<WzElementPermissions
permissions={permissions}
roles={roles}
tooltip={tooltip}
getAdditionalProps={disabled => {
const additionalProps = {
...(!['link', 'switch'].includes(buttonType)
? { isDisabled: disabled }
: { disabled }),
onClick:
disabled || !rest.onClick || buttonType == 'switch'
? undefined
: rest.onClick,
onChange: disabled || !rest.onChange ? undefined : rest.onChange,
};

if (buttonType == 'switch') delete customProps.onClick;
if (buttonType == 'switch') delete additionalProps.onClick;

const button = <Button {...customProps} {...disabledProp} />;

const buttonTextRequirements = (userRolesRequirements || userPermissionRequirements) && (
<Fragment>
{userPermissionRequirements && (
<div>
<div>Require the {userPermissionRequirements.length === 1 ? 'permission' : 'permissions'}:</div>
{WzPermissionsFormatted(userPermissionRequirements)}
</div>
)}
{(userPermissionRequirements && userRolesRequirements) && <EuiSpacer size='s' />}
{userRolesRequirements && (
<div>
Require {userRolesRequirements.map(role => <strong key={`empty-prompt-no-roles-${role}`}>{role}</strong>).reduce((prev, cur) => [prev, ', ' , cur])} {userRolesRequirements.length > 1 ? 'roles': 'role'}
</div>
)}
</Fragment>
)
return (userRolesRequirements || userPermissionRequirements) ?
(<EuiToolTip
{...tooltip}
content={buttonTextRequirements}
return additionalProps;
}}
>
{button}
</EuiToolTip>) : tooltip && tooltip.content ?
(<EuiToolTip
{...tooltip}
>
{button}
</EuiToolTip>)
: button
}
<Button {...rest} />
</WzElementPermissions>
);
};
109 changes: 109 additions & 0 deletions plugins/main/public/components/common/permissions/element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Wazuh app - Button with Wazuh API permissions and/or roles required to be useful
* Copyright (C) 2015-2022 Wazuh, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Find more information about this on the LICENSE file.
*/

import React, { Fragment } from 'react';
import { useUserPermissionsRequirements } from '../hooks/useUserPermissions';
import { useUserRolesRequirements } from '../hooks/useUserRoles';

import { EuiToolTip, EuiSpacer } from '@elastic/eui';

import { WzPermissionsFormatted } from './format';

export interface IUserPermissionsObject {
action: string;
resource: string;
}
export type TUserPermissionsFunction = (props: any) => TUserPermissions;
export type TUserPermissions = (string | IUserPermissionsObject)[] | null;
export type TUserRoles = string[] | null;
export type TUserRolesFunction = (props: any) => TUserRoles;

export interface IWzElementPermissionsProps {
permissions?: TUserPermissions | TUserPermissionsFunction;
roles?: TUserRoles | TUserRolesFunction;
tooltip?: any;
children: React.ReactElement;
getAdditionalProps?: (disabled: boolean) => {
[prop: string]: any;
};
}

export const WzElementPermissions = ({
children,
permissions = null,
roles = null,
getAdditionalProps,
tooltip,
...rest
}: IWzElementPermissionsProps) => {
const [userPermissionRequirements] = useUserPermissionsRequirements(
typeof permissions === 'function' ? permissions(rest) : permissions,
);
const [userRolesRequirements] = useUserRolesRequirements(
typeof roles === 'function' ? roles(rest) : roles,
);

const isDisabledByRolesOrPermissions =
userRolesRequirements || userPermissionRequirements;

const disabled = Boolean(
isDisabledByRolesOrPermissions || rest?.isDisabled || rest?.disabled,
);

const additionalProps = getAdditionalProps
? getAdditionalProps(disabled)
: {};

const childrenWithAdditionalProps = React.cloneElement(children, {
...additionalProps,
});

const contentTextRequirements = isDisabledByRolesOrPermissions && (
<Fragment>
{userPermissionRequirements && (
<div>
<div>
Require the{' '}
{userPermissionRequirements.length === 1
? 'permission'
: 'permissions'}
:
</div>
{WzPermissionsFormatted(userPermissionRequirements)}
</div>
)}
{userPermissionRequirements && userRolesRequirements && (
<EuiSpacer size='s' />
)}
{userRolesRequirements && (
<div>
Require{' '}
{userRolesRequirements
.map(role => (
<strong key={`empty-prompt-no-roles-${role}`}>{role}</strong>
))
.reduce((prev, cur) => [prev, ', ', cur])}{' '}
{userRolesRequirements.length > 1 ? 'roles' : 'role'}
</div>
)}
</Fragment>
);
return isDisabledByRolesOrPermissions ? (
<EuiToolTip {...tooltip} content={contentTextRequirements}>
{childrenWithAdditionalProps}
</EuiToolTip>
) : tooltip && tooltip.content ? (
<EuiToolTip {...tooltip}>{childrenWithAdditionalProps}</EuiToolTip>
) : (
childrenWithAdditionalProps
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
TUserPermissionsFunction,
TUserRoles,
TUserRolesFunction,
} from '../permissions/button';
} from '../permissions/element';
import { WzPermissionsFormatted } from './format';
import { withErrorBoundary } from '../hocs/error-boundary/with-error-boundary';

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export class GroupTruncate extends React.Component {
popoverOpen: boolean;
};
props!: {
groups?: string[];
label: String;
length: number;
agent: Object;
action: String;
filterAction: any;
};
Expand Down Expand Up @@ -100,10 +100,10 @@ export class GroupTruncate extends React.Component {
);
}

renderGroups(groups = []) {
renderGroups(groups: string[] = []) {
const { length } = this.props;
let auxGroups: Array<String> = [];
let tooltipGroups: Array<String> = [];
let auxGroups: Array<React.ReactNode> = [];
let tooltipGroups: Array<React.ReactNode> = [];
let auxLength = 0;
let auxIndex = 0;
if (groups.length >= 2 && groups.toString().length >= length) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { AgentGroupTruncate } from './agent_group_truncate';
export { GroupTruncate } from './group-truncate';
export { GroupTruncate } from './group-truncate';
10 changes: 5 additions & 5 deletions plugins/main/public/components/common/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* Find more information about this on the LICENSE file.
*/

export { AgentGroupTruncate, GroupTruncate} from './agent-group-truncate';
export { TruncateHorizontalComponents } from './truncate-horizontal-components/truncate-horizontal-components';
export { GroupingComponents } from './grouping-components';
export * from './markdown/markdown';
export * from './wz-overlay-mask-interface';
export { GroupTruncate } from './agent-group-truncate';
export { TruncateHorizontalComponents } from './truncate-horizontal-components/truncate-horizontal-components';
export { GroupingComponents } from './grouping-components';
export * from './markdown/markdown';
export * from './wz-overlay-mask-interface';
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ export class AgentInfo extends Component {
length={40}
label={'more'}
action={'redirect'}
agent={this.props.agent}
{...this.props}
/>
) : item.description === 'Operating system' ? (
Expand Down
Loading

0 comments on commit e649ae2

Please sign in to comment.