Skip to content

[data_release] Introduce Manage File, Revamp Manage Permissions, Hide, Delete #9445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion SQL/0000-00-00-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2111,8 +2111,10 @@ CREATE TABLE `data_release` (
`version` varchar(255),
`upload_date` date,
`ProjectID` INT(10) UNSIGNED NULL,
`hidden_by_userid` INT(10) UNSIGNED NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (ProjectID) REFERENCES Project (ProjectID)
FOREIGN KEY (ProjectID) REFERENCES Project (ProjectID),
FOREIGN KEY (hidden_by_userid) REFERENCES users (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `data_release_permissions` (
Expand Down
2 changes: 2 additions & 0 deletions SQL/0000-00-02-Permission.sql
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ INSERT INTO `permissions` (code, description, moduleID, action, categoryID) VALU
('data_release_view', 'Release Files',(SELECT ID FROM modules WHERE Name='data_release'),'View', 2),
('data_release_upload', 'Release Files',(SELECT ID FROM modules WHERE Name='data_release'),'Upload', 2),
('data_release_edit_file_access', 'Grant Other Users Access to Releases',(SELECT ID FROM modules WHERE Name='data_release'),NULL, 2),
('data_release_hide', 'Hide data release files',(SELECT ID FROM modules WHERE Name='data_release'),NULL, 2),
('data_release_delete', 'Delete data release files',(SELECT ID FROM modules WHERE Name='data_release'),NULL, 2),
('instrument_manager_read', 'Installed Instruments',(SELECT ID FROM modules WHERE Name='instrument_manager'),'View', 2),
('instrument_manager_write', 'Upload and Install Instruments',(SELECT ID FROM modules WHERE Name='instrument_manager'),NULL, 2),
('publication_view', 'Publication Projects',(SELECT ID FROM modules WHERE Name='publication'),'View', 2),
Expand Down
9 changes: 9 additions & 0 deletions SQL/New_patches/2024-10-31-Data_Release_Hide_File.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ALTER TABLE data_release
ADD COLUMN hidden_by_userid int(10) unsigned NULL DEFAULT NULL,
ADD CONSTRAINT FK_hidden_by_userid
FOREIGN KEY (hidden_by_userid) REFERENCES users (ID);

INSERT INTO permissions (moduleID, code, action, description, categoryID)
SELECT ID, 'data_release_hide', 'Edit', 'Hidden Releases', 2 FROM modules WHERE Name = 'data_release';
INSERT INTO permissions (moduleID, code, action, description, categoryID)
SELECT ID, 'data_release_delete', 'Delete', 'Releases', 2 FROM modules WHERE Name = 'data_release';
2 changes: 2 additions & 0 deletions modules/data_release/help/data_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ Click **Upload File** to upload a file and specify a version (based on your own
Click **Add Permission** to grant access to any of your users at the file or version level.

Click **Manage Permissions** to modify existing user permissions.

Click on the pencil beside the file name to edit file access, hide or delete the file.
84 changes: 60 additions & 24 deletions modules/data_release/jsx/addPermissionForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AddPermissionForm extends Component {
errorMessage: {},
isLoaded: false,
loadedData: 0,
specificReleaseId: null,
};

this.setFormData = this.setFormData.bind(this);
Expand Down Expand Up @@ -58,7 +59,21 @@ class AddPermissionForm extends Component {
* Called by React when the component has been rendered on the page.
*/
componentDidMount() {
this.fetchData().then(() => this.setState({isLoaded: true}));
// if data was not provided from manageFileForm, fetch it.
if (!this.props.data) {
this.fetchData()
.then(() => this.setState({isLoaded: true}));
} else {
this.setState({
data: this.props.data,
fieldOptions: this.props.fieldOptions,
isLoaded: true,
specificReleaseId: this.props.specificReleaseId,
formData: {
data_release_id: this.props.specificReleaseId,
},
});
}
}

/**
Expand Down Expand Up @@ -97,31 +112,48 @@ class AddPermissionForm extends Component {
errorMessage={this.state.errorMessage.Username}
required={true}
value={this.state.formData.userid}
/>
<h3>Choose a specific file or an entire release below</h3><br/>
<SelectElement
name='data_release_id'
label='Data Release File'
options={this.state.fieldOptions.filenames}
onUserInput={this.setFormData}
ref='data_release_id'
errorMessage={this.state.errorMessage.Filename}
required={false}
value={this.state.formData.data_release_id}
autoSelect={false}
/>
<h4>OR</h4><br/>
<SelectElement
name='data_release_version'
label='Data Release Version'
options={this.state.fieldOptions.versions}
onUserInput={this.setFormData}
ref='data_release_version'
errorMessage={this.state.errorMessage.Version}
required={false}
value={this.state.formData.data_release_version}
autoSelect={false}
/>
{this.state.specificReleaseId === null ?
<>
<h3>Choose a specific file or an entire release below</h3><br/>
<SelectElement
name='data_release_id'
label='Data Release File'
options={this.state.fieldOptions.filenames}
onUserInput={this.setFormData}
ref='data_release_id'
errorMessage={this.state.errorMessage.Filename}
required={false}
value={this.state.formData.data_release_id}
autoSelect={false}
/>
<h4>OR</h4><br/>
<SelectElement
name='data_release_version'
label='Data Release Version'
options={this.state.fieldOptions.versions}
onUserInput={this.setFormData}
ref='data_release_version'
errorMessage={this.state.errorMessage.Version}
required={false}
value={this.state.formData.data_release_version}
autoSelect={false}
/>
</>
:
// If from manageFileForm, don't allow user to change the file
<SelectElement
name='data_release_id'
label='Data Release File'
options={this.state.fieldOptions.filenames}
onUserInput={() => {}}
ref='data_release_id'
disabled={true}
value={this.state.specificReleaseId}
autoSelect={false}
/>
}
<ButtonElement label='Add Permission'/>
</FormElement>
);
Expand Down Expand Up @@ -228,6 +260,10 @@ AddPermissionForm.propTypes = {
DataURL: PropTypes.string.isRequired,
action: PropTypes.string.isRequired,
fetchData: PropTypes.func,
data_release_id: PropTypes.number,
specificReleaseId: PropTypes.number,
fieldOptions: PropTypes.object,
data: PropTypes.object,
};

export default AddPermissionForm;
78 changes: 73 additions & 5 deletions modules/data_release/jsx/dataReleaseIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Modal from 'Modal';
import UploadFileForm from './uploadFileForm';
import AddPermissionForm from './addPermissionForm';
import ManagePermissionsForm from './managePermissionsForm';
import ManageFileForm from './manageFileForm';

/**
* Data Release
Expand All @@ -33,7 +34,9 @@ class DataReleaseIndex extends Component {
uploadFileForm: false,
addPermissionForm: false,
managePermissionsForm: false,
manageFileForm: false,
},
managingFile: null,
};

this.fetchData = this.fetchData.bind(this);
Expand Down Expand Up @@ -80,7 +83,9 @@ class DataReleaseIndex extends Component {
fetchData() {
return fetch(this.props.dataURL, {credentials: 'same-origin'})
.then((resp) => resp.json())
.then((data) => this.setState({data}))
.then((data) => {
this.setState({data});
})
.catch((error) => {
this.setState({error: true});
console.error(error);
Expand All @@ -97,7 +102,11 @@ class DataReleaseIndex extends Component {
*/
formatColumn(column, cell, row) {
// Set class to 'bg-danger' if file is hidden.
let result = <td>{cell}</td>;
let hidden = row['Hidden By ID']
&& this.props.hasPermission('data_release_hide');
let result = <td
className={hidden ? 'bg-danger' : ''}
>{cell}</td>;
switch (column) {
case 'File Name':
if (this.props.hasPermission('superuser')
Expand All @@ -108,17 +117,50 @@ class DataReleaseIndex extends Component {
+ '/data_release/files/'
+ encodeURIComponent(row['Data Release ID']);
result = (
<td>
<td
className={hidden ? 'bg-danger' : ''}
style={{display: 'flex',
justifyContent: 'space-between',
}}
>
<a
href = {downloadURL}
target = "_blank"
download = {row['File Name']} >
{cell}
</a>
{
(this.props.hasPermission('data_release_edit_file_access')
|| this.props.hasPermission('data_release_delete')
|| this.props.hasPermission('data_release_hide')
) &&
<a
style={{marginLeft: 'auto'}}
onClick={() => {
this.setState({
managingFile: {
fileName: row['File Name'],
version: row['Version'],
hiddenById: row['Hidden By ID'],
dataReleaseID: row['Data Release ID'],
},
});
this.show('manageFileForm');
}}
>
<span className='glyphicon glyphicon-pencil' />
</a>
}
</td>
);
}
break;
case 'Version':
result = <td
className={hidden ? 'bg-danger' : ''}>
{cell}
</td>;
break;
}
return result;
}
Expand Down Expand Up @@ -151,7 +193,8 @@ class DataReleaseIndex extends Component {
}},
{label: 'Version', show: true, filter: {
name: 'version',
type: 'text',
type: 'select',
options: this.state.data.fieldOptions.versions,
}},
{label: 'Upload Date', show: true, filter: {
name: 'uploadDate',
Expand All @@ -162,8 +205,11 @@ class DataReleaseIndex extends Component {
type: 'select',
options: this.state.data.fieldOptions.projects,
}},
{label: 'Data Release ID', show: false,
{label: 'Data Release ID',
show: false,
name: 'dataReleaseID',
},
{label: 'Hidden By ID', show: false},
];

// Upload File modal window
Expand All @@ -184,6 +230,7 @@ class DataReleaseIndex extends Component {
}
action={loris.BaseURL + '/data_release/files'}
projects={this.state.data.fieldOptions.projects}
versions={this.state.data.fieldOptions.versions}
/>
</Modal>
);
Expand Down Expand Up @@ -231,6 +278,26 @@ class DataReleaseIndex extends Component {
onClose={() => this.hide('managePermissionsForm')}
/>
);
// Manage File modal window
const manageFileForm = (
<Modal
title="Manage File"
label="Manage File"
show={this.state.show.manageFileForm}
onClose={() => {
this.hide('manageFileForm');
}}
onClick={this.manageFile}
>
<ManageFileForm
DataURL={`${loris.BaseURL}/data_release/?format=json`}
manageFileActions={`${loris.BaseURL}/data_release/files/`}
managePermissionActions={`${loris.BaseURL}/data_release/permissions`}
fetchData={this.fetchData}
managingFile={this.state.managingFile}
/>
</Modal>
);

const actions = [
{
Expand All @@ -257,6 +324,7 @@ class DataReleaseIndex extends Component {
<div>
{uploadFileForm}
{addPermissionForm}
{manageFileForm}
{managePermissionsForm}
<FilterableDataTable
name="data_release"
Expand Down
Loading
Loading