Skip to content

Commit

Permalink
Merge pull request #746 from swaterkamp/BulkTags
Browse files Browse the repository at this point in the history
Bulk Tags
  • Loading branch information
bjoernricks authored Jun 26, 2018
2 parents 164dd16 + 02e3e01 commit 895955f
Show file tree
Hide file tree
Showing 7 changed files with 411 additions and 34 deletions.
2 changes: 2 additions & 0 deletions gsa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ set (GSA_JS_SRC_FILES
${GSA_SRC_DIR}/src/web/components/icon/osicon.js
${GSA_SRC_DIR}/src/web/components/icon/restoreicon.js
${GSA_SRC_DIR}/src/web/components/icon/solutiontypeicon.js
${GSA_SRC_DIR}/src/web/components/icon/tagsicon.js
${GSA_SRC_DIR}/src/web/components/icon/trashdeleteicon.js
${GSA_SRC_DIR}/src/web/components/icon/trashicon.js
${GSA_SRC_DIR}/src/web/components/icon/withIconCss.js
Expand Down Expand Up @@ -344,6 +345,7 @@ set (GSA_JS_SRC_FILES
${GSA_SRC_DIR}/src/web/entities/row.js
${GSA_SRC_DIR}/src/web/entities/selection.js
${GSA_SRC_DIR}/src/web/entities/table.js
${GSA_SRC_DIR}/src/web/entities/tagsdialog.js
${GSA_SRC_DIR}/src/web/entities/withEntitiesContainer.js
${GSA_SRC_DIR}/src/web/entities/withRowDetails.js
${GSA_SRC_DIR}/src/web/entity/block.js
Expand Down
6 changes: 5 additions & 1 deletion gsa/src/gmp/commands/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*
* Authors:
* Björn Ricks <[email protected]>
* Steffen Waterkamp <[email protected]>
*
* Copyright:
* Copyright (C) 2017 - 2018 Greenbone Networks GmbH
Expand Down Expand Up @@ -66,7 +67,9 @@ class TagCommand extends EntityCommand {
name,
comment = '',
active,
filter,
resource_id = '',
resource_ids = [resource_id],
resource_type,
value = '',
}) {
Expand All @@ -77,7 +80,8 @@ class TagCommand extends EntityCommand {
tag_value: value,
comment,
active,
resource_id,
filter,
'resource_ids:': resource_ids.length > 0 ? resource_ids : undefined,
resource_type,
};
log.debug('Saving tag', data);
Expand Down
69 changes: 69 additions & 0 deletions gsa/src/web/components/icon/tagsicon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* Greenbone Security Assistant
*
* Authors:
* Steffen Waterkamp <[email protected]>
*
* Copyright:
* Copyright (C) 2018 Greenbone Networks GmbH
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import React from 'react';

import _ from 'gmp/locale.js';
import {is_defined} from 'gmp/utils';

import PropTypes from '../../utils/proptypes.js';

import SelectionType from '../../utils/selectiontype.js';

import Icon from './icon.js';

const TagsIcon = ({
active = true,
selectionType,
title,
...other
}) => {
if (!is_defined(title)) {
if (selectionType === SelectionType.SELECTION_PAGE_CONTENTS) {
title = _('Add tag to page contents');
}
else if (selectionType === SelectionType.SELECTION_USER) {
title = _('Add tag to selection');
}
else if (selectionType === SelectionType.SELECTION_FILTER) {
title = _('Add tag to filtered');
}
}
return (
<Icon
{...other}
img={'tag.svg'}
title={title}/>
);
};

TagsIcon.propTypes = {
active: PropTypes.bool,
selectionType: PropTypes.string,
title: PropTypes.string,
onClick: PropTypes.func,
};

export default TagsIcon;

// vim: set ts=2 sw=2 tw=80:
64 changes: 62 additions & 2 deletions gsa/src/web/entities/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import withDialogNotification from '../components/notification/withDialogNotifia

import SortBy from '../components/sortby/sortby.js';

import TagsDialog from './tagsdialog.js';

const log = logger.getLogger('web.entities.container');

const exclude_props = [
Expand All @@ -68,6 +70,8 @@ class EntitiesContainer extends React.Component {
loading: false,
updating: false,
selection_type: SelectionType.SELECTION_PAGE_CONTENTS,
tags: [],
tagsDialogVisible: false,
};

const {gmpname, gmp, notify} = this.props;
Expand All @@ -90,6 +94,7 @@ class EntitiesContainer extends React.Component {

this.handleChanged = this.handleChanged.bind(this);
this.handleDeselected = this.handleDeselected.bind(this);
this.handleDeleteBulk = this.handleDeleteBulk.bind(this);
this.handleDownloadBulk = this.handleDownloadBulk.bind(this);
this.handleError = this.handleError.bind(this);
this.handleFirst = this.handleFirst.bind(this);
Expand All @@ -103,6 +108,8 @@ class EntitiesContainer extends React.Component {
this.handleFilterCreated = this.handleFilterCreated.bind(this);
this.handleFilterChanged = this.handleFilterChanged.bind(this);
this.handleFilterReset = this.handleFilterReset.bind(this);
this.openTagsDialog = this.openTagsDialog.bind(this);
this.closeTagsDialog = this.closeTagsDialog.bind(this);
}

componentDidMount() {
Expand All @@ -129,7 +136,6 @@ class EntitiesContainer extends React.Component {
this.load({filter, reload});
}


load(options = {}) {
const {entities_command} = this;
const {filter, force = false, reload = false} = options;
Expand Down Expand Up @@ -162,6 +168,9 @@ class EntitiesContainer extends React.Component {
const {data: entities, meta} = response;
const {filter: loaded_filter, counts: entities_counts} = meta; // eslint-disable-line no-shadow

const entitiesType = entities.length > 0 ?
entities[0].entity_type : undefined;

this.cancel = undefined;

let refresh = false;
Expand All @@ -175,6 +184,7 @@ class EntitiesContainer extends React.Component {
this.setState({
entities,
entities_counts,
entitiesType,
filter,
loaded_filter,
loading: false,
Expand Down Expand Up @@ -396,23 +406,61 @@ class EntitiesContainer extends React.Component {
this.load();
}

openTagsDialog() {
this.getTagsByType();
this.setState({tagsDialogVisible: true});
}

closeTagsDialog() {
this.setState({tagsDialogVisible: false});
}

getTagsByType() {
const {gmp} = this.props;
const {entitiesType} = this.state;
const filter = 'resource_type=' + entitiesType;
gmp.tags.getAll({filter})
.then(response => {
const {data} = response;
this.setState({tags: data});
});
}

render() {
const {
entities,
entities_counts,
loaded_filter,
loading,
selected,
selected = {},
selection_type,
sortBy,
sortDir,
tags,
tagsDialogVisible,
updating,
} = this.state;
const {
onDownload,
showErrorMessage,
showSuccessMessage,
} = this.props;

let entitiesType;
if (is_defined(entities) && is_defined(entities[0])) {
entitiesType = entities[0].entity_type;
}

let title;
if (selection_type === SelectionType.SELECTION_USER) {
title = 'Add Tag to Selection';
}
else if (selection_type === SelectionType.SELECTION_PAGE_CONTENTS) {
title = 'Add Tag to Page Contents';
}
else {
title = 'Add Tag to All Filtered';
}
const Component = this.props.component;
const other = exclude_object_props(this.props, exclude_props);
return (
Expand All @@ -437,6 +485,7 @@ class EntitiesContainer extends React.Component {
onSelectionTypeChange={this.handleSelectionTypeChange}
onDownloadBulk={this.handleDownloadBulk}
onDeleteBulk={this.handleDeleteBulk}
onTagsBulk={this.openTagsDialog}
onEntitySelected={this.handleSelected}
onEntityDeselected={this.handleDeselected}
onFilterCreated={this.handleFilterCreated}
Expand All @@ -448,6 +497,17 @@ class EntitiesContainer extends React.Component {
showSuccess={showSuccessMessage}
updating={updating}
/>
{tagsDialogVisible &&
<TagsDialog
filter={loaded_filter}
tags={tags}
title={title}
resources={selected}
resourceType={entitiesType}
selectionType={selection_type}
onClose={this.closeTagsDialog}
/>
}
</Wrapper>
);
}
Expand Down
23 changes: 21 additions & 2 deletions gsa/src/web/entities/footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
*
* Authors:
* Björn Ricks <[email protected]>
* Steffen Waterkamp <[email protected]>
*
* Copyright:
* Copyright (C) 2016 - 2017 Greenbone Networks GmbH
* Copyright (C) 2016 - 2018 Greenbone Networks GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
Expand Down Expand Up @@ -34,6 +35,7 @@ import SelectionType from '../utils/selectiontype.js';

import DeleteIcon from '../components/icon/deleteicon.js';
import ExportIcon from '../components/icon/exporticon.js';
import TagsIcon from '../components/icon/tagsicon.js';
import TrashIcon from '../components/icon/trashicon.js';

import Select from '../components/form/select.js';
Expand All @@ -48,10 +50,12 @@ export const EntitiesFooter = ({
selection = true,
selectionType,
span,
tags = true,
trash,
onDeleteClick,
onDownloadClick,
onSelectionTypeChange,
onTagsClick,
onTrashClick,
...props
}) => {
Expand Down Expand Up @@ -79,6 +83,12 @@ export const EntitiesFooter = ({
</Select>
}
<IconDivider>
{tags &&
<TagsIcon
onClick={onTagsClick}
selectionType={selectionType}
/>
}
{trash &&
<TrashIcon
onClick={onTrashClick}
Expand Down Expand Up @@ -113,22 +123,30 @@ EntitiesFooter.propTypes = {
selection: PropTypes.bool,
selectionType: PropTypes.string,
span: PropTypes.number.isRequired,
tags: PropTypes.bool,
trash: PropTypes.bool,
onDeleteClick: PropTypes.func,
onDownloadClick: PropTypes.func,
onSelectionTypeChange: PropTypes.func,
onTagsClick: PropTypes.func,
onTrashClick: PropTypes.func,
};

export const withEntitiesFooter = (options = {}) => Component => {

const EntitiesFooterWrapper = ({onDownloadBulk, onDeleteBulk, ...props}) => {
const EntitiesFooterWrapper = ({
onDownloadBulk,
onDeleteBulk,
onTagsBulk,
...props
}) => {
return (
<Component
{...options}
{...props}
onDownloadClick={onDownloadBulk}
onDeleteClick={onDeleteBulk}
onTagsClick={onTagsBulk}
onTrashClick={onDeleteBulk}
/>
);
Expand All @@ -137,6 +155,7 @@ export const withEntitiesFooter = (options = {}) => Component => {
EntitiesFooterWrapper.propTypes = {
onDeleteBulk: PropTypes.func,
onDownloadBulk: PropTypes.func,
onTagsBulk: PropTypes.func,
};

return EntitiesFooterWrapper;
Expand Down
Loading

0 comments on commit 895955f

Please sign in to comment.