Skip to content

Commit

Permalink
share modal: add groups tab by feature flag
Browse files Browse the repository at this point in the history
* closes #2592
  • Loading branch information
anikachurilova authored and ntarocco committed May 7, 2024
1 parent 08ecc75 commit 0d99664
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
data-current-user-id="{{ current_user.id }}"
data-record-owner-username='{{ record_owner_username }}'
data-access-links-search-config='{{ search_app_access_links_config(app_id="InvenioAppRdm.AccessLinks", endpoint=record.links.access_links) | tojson }}'
data-groups-enabled='{{ config.USERS_RESOURCES_GROUPS_ENABLED | tojson }}'
>
<div class="ui placeholder">
<div class="header">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class RecordManagement extends Component {
currentUserId,
accessLinksSearchConfig,
recordOwnerUsername,
groupsEnabled,
} = this.props;
const { error } = this.state;
const { id: recid } = record;
Expand Down Expand Up @@ -88,6 +89,7 @@ export class RecordManagement extends Component {
record={record}
accessLinksSearchConfig={accessLinksSearchConfig}
permissions={permissions}
groupsEnabled={groupsEnabled}
/>
)}
</Grid.Column>
Expand Down Expand Up @@ -115,6 +117,7 @@ RecordManagement.propTypes = {
record: PropTypes.object.isRequired,
permissions: PropTypes.object.isRequired,
isDraft: PropTypes.bool.isRequired,
groupsEnabled: PropTypes.bool.isRequired,
isPreviewSubmissionRequest: PropTypes.bool.isRequired,
currentUserId: PropTypes.string.isRequired,
recordOwnerUsername: PropTypes.object.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
// Invenio RDM Records is free software; you can redistribute it and/or modify it
// under the terms of the MIT License; see LICENSE file for more details.
import _isEmpty from "lodash/isEmpty";
import { UserAccessSearchResult } from "./UserAccessSearchResult";
import { UserGroupAccessSearchResult } from "./UserGroupAccessSearchResult";
import React, { Component } from "react";
import { Modal, Loader, Button, Container } from "semantic-ui-react";
import PropTypes from "prop-types";
import { withCancel } from "react-invenio-forms";
import { http } from "react-invenio-forms";
import { i18next } from "@translations/invenio_app_rdm/i18next";

export class AccessUsers extends Component {
export class AccessUsersGroups extends Component {
constructor(props) {
super(props);
this.state = {
Expand All @@ -35,12 +35,10 @@ export class AccessUsers extends Component {
};

fetchData = async () => {
const { record } = this.props;
const { endpoint } = this.props;
this.setState({ loading: true });
try {
this.cancellableAction = withCancel(
http.get(`${record.links.access_users}?expand=true`)
);
this.cancellableAction = withCancel(http.get(`${endpoint}?expand=true`));
const response = await this.cancellableAction.promise;
this.setState({
loading: false,
Expand All @@ -58,26 +56,51 @@ export class AccessUsers extends Component {
};

render() {
const { record, handleClose, permissions } = this.props;
const {
record,
handleClose,
permissions,
emptyResultText,
tableHeaderText,
addButtonText,
endpoint,
searchBarTitle,
selectedItemsHeader,
fetchMembers,
searchType,
searchBarTooltip,
searchBarPlaceholder,
doneButtonTipType,
} = this.props;
const { results, loading, error } = this.state;
return (
<>
{error && error}
<Modal.Content>
{loading && <Loader isLoading active />}
{!loading && results !== undefined && (
<UserAccessSearchResult
<UserGroupAccessSearchResult
permissions={permissions}
results={results}
record={record}
fetchData={this.fetchData}
recOwner={record?.expanded?.parent?.access?.owned_by}
setError={this.setError}
tableHeaderText={tableHeaderText}
addButtonText={addButtonText}
searchBarTitle={searchBarTitle}
selectedItemsHeader={selectedItemsHeader}
endpoint={endpoint}
record={record}
fetchMembers={fetchMembers}
searchType={searchType}
searchBarTooltip={searchBarTooltip}
searchBarPlaceholder={searchBarPlaceholder}
doneButtonTipType={doneButtonTipType}
/>
)}
{_isEmpty(results) && (
<Container className="mt-10" textAlign="center">
<h5>{i18next.t("No user has access to this record yet.")}</h5>
<h5>{emptyResultText}</h5>
</Container>
)}
</Modal.Content>
Expand All @@ -94,8 +117,30 @@ export class AccessUsers extends Component {
}
}

AccessUsers.propTypes = {
AccessUsersGroups.propTypes = {
record: PropTypes.object.isRequired,
handleClose: PropTypes.func.isRequired,
permissions: PropTypes.object.isRequired,
endpoint: PropTypes.string.isRequired,
emptyResultText: PropTypes.string,
tableHeaderText: PropTypes.string,
addButtonText: PropTypes.string,
searchBarTitle: PropTypes.string,
doneButtonTipType: PropTypes.string,
searchBarTooltip: PropTypes.string,
searchBarPlaceholder: PropTypes.string,
selectedItemsHeader: PropTypes.string,
fetchMembers: PropTypes.func.isRequired,
searchType: PropTypes.oneOf(["group", "user"]).isRequired,
};

AccessUsersGroups.defaultProps = {
emptyResultText: "",
tableHeaderText: "",
addButtonText: "",
searchBarTitle: "",
searchBarTooltip: "",
selectedItemsHeader: "",
searchBarPlaceholder: "",
doneButtonTipType: "",
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { SearchWithRoleSelection } from "@js/invenio_communities/members";
import { RichEditor } from "react-invenio-forms";
import { GrantAccessApi } from "../api/api";

export class AddUserAccessModal extends Component {
export class AddUserGroupAccessModal extends Component {
constructor(props) {
super(props);
this.state = { open: false, notifyUser: true, message: undefined };
Expand All @@ -39,7 +39,20 @@ export class AddUserAccessModal extends Component {
};

render() {
const { results, record, isComputer, accessDropdownOptions } = this.props;
const {
results,
record,
isComputer,
accessDropdownOptions,
addButtonText,
searchBarTitle,
selectedItemsHeader,
fetchMembers,
searchType,
searchBarTooltip,
searchBarPlaceholder,
doneButtonTipType,
} = this.props;
const { open, notifyUser, message } = this.state;

const api = new GrantAccessApi(record);
Expand All @@ -56,11 +69,11 @@ export class AddUserAccessModal extends Component {
onOpen={this.handleOpenModal}
closeOnDimmerClick={false}
open={open}
aria-label={i18next.t("Add people")}
aria-label={addButtonText}
trigger={
<Button
className={!isComputer ? "mobile only tablet only mb-15" : ""}
content={i18next.t("Add people")}
content={addButtonText}
positive
size="medium"
icon="plus"
Expand All @@ -69,22 +82,22 @@ export class AddUserAccessModal extends Component {
/>
}
>
<Modal.Header as="h2">{i18next.t("Add people")}</Modal.Header>
<Modal.Header as="h2">{addButtonText}</Modal.Header>
<SearchWithRoleSelection
key="access-users"
roleOptions={accessDropdownOptions}
modalClose={this.handleCloseModal}
action={api.createGrants}
fetchMembers={fetchMembers}
onSuccessCallback={this.onSuccess}
searchBarTitle={<label>{i18next.t("User")}</label>}
searchBarTooltip={i18next.t(
"Search for users to grant access (only users with a public profile can be invited)"
)}
searchBarTitle={<label>{searchBarTitle}</label>}
searchBarTooltip={searchBarTooltip}
doneButtonText={i18next.t("Add")}
doneButtonIcon="plus"
radioLabel={i18next.t("Access")}
selectedItemsHeader={i18next.t("Selected users")}
selectedItemsHeader={selectedItemsHeader}
message={message}
searchType={searchType}
messageComponent={
<>
<Checkbox
Expand All @@ -96,7 +109,7 @@ export class AddUserAccessModal extends Component {
{notifyUser && (
<>
<p>
<b>{i18next.t("Message")}</b>
<b>{i18next.t("Invitation message")}</b>
</p>
<RichEditor
onBlur={(event, editor) => {
Expand All @@ -109,18 +122,37 @@ export class AddUserAccessModal extends Component {
}
notify={notifyUser}
doneButtonTip={i18next.t("You are about to add")}
doneButtonTipType={doneButtonTipType}
existingEntities={existingIds}
existingEntitiesDescription={i18next.t("Access already granted")}
searchBarPlaceholder={searchBarPlaceholder}
/>
</Modal>
);
}
}

AddUserAccessModal.propTypes = {
AddUserGroupAccessModal.propTypes = {
record: PropTypes.object.isRequired,
results: PropTypes.array.isRequired,
isComputer: PropTypes.bool.isRequired,
accessDropdownOptions: PropTypes.array.isRequired,
fetchData: PropTypes.func.isRequired,
addButtonText: PropTypes.string,
searchBarTitle: PropTypes.string,
searchBarPlaceholder: PropTypes.string,
searchBarTooltip: PropTypes.string,
doneButtonTipType: PropTypes.string,
selectedItemsHeader: PropTypes.string,
fetchMembers: PropTypes.func.isRequired,
searchType: PropTypes.oneOf(["group", "user"]).isRequired,
};

AddUserGroupAccessModal.defaultProps = {
addButtonText: "",
searchBarTitle: "",
searchBarTooltip: "",
selectedItemsHeader: "",
searchBarPlaceholder: "",
doneButtonTipType: "",
};
Loading

0 comments on commit 0d99664

Please sign in to comment.