Skip to content

Conversation

@regisoc
Copy link
Contributor

@regisoc regisoc commented Jul 11, 2025

Brief summary of changes

This PR adds a UI for designated users with new permission redcap_ui_view.

The UI is mainly targeted at people managing REDCap data integration, and adapts to one or multiple connected REDCap instances and projects.
The current UI composed by 3 tabs (more can be added) to give information and help navigate, this is particularly useful for issues arising when importing REDCap data e.g. missing notifications, network issues, out-of-sync instruments dictionary.

Images of current included tabs

Notifications received:

redcap_ui_notification

REDCap Dictionary in use:

redcap_ui_dictionary

REDCap import issues in issue tracker:

redcap_ui_issue

This PR also updates the redcap2linst:

  • location to module/redcap/tools as a module specific tool.
  • process to include an automatic redcap_dictionary table update when parsing the redcap dictionary.

To discuss:

  • Caveat:
  • Extract REDCap issues from issue tracker to their own "log-like" table/structure. As there can be a LOT of issues created under classical import conditions, or even in mass import cases, it could be useful to extract the REDCap issue process creation to some other structure or another table.

Testing instructions (if applicable)

  1. Activate the redcap module in modules manager.
  2. Go to Tools > REDCap menu item.

@regisoc regisoc added Category: Feature PR or issue that aims to introduce a new feature Area: UI PR or issue related to the user interface Language: SQL PR or issue that update SQL code Proposal PR or issue suggesting an improvement that can be accepted, rejected or altered Language: PHP PR or issue that update PHP code Language: Javascript PR or issue that update Javascript code Area: Instruments PR or issue related instruments Release: SQL patch PR that contains an SQL patch to apply Module: redcap PR or issue related to redcap module labels Jul 11, 2025
@github-actions github-actions bot added the RaisinBread PR or issue introducing/requiring improvements to the Raidinbread dataset label Jul 11, 2025
Copy link
Contributor

@MaximeBICMTL MaximeBICMTL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is just a work-in-progress, but I did a small review notably of the Javascript side.

I know this requires some work, but I would heavily prefer to use Typescript and function components for the UI, untyped JS and class components are a lot harder to maintain in my opinion and I would rather not have them in newer code.

This is my main concern, outside of that, all the nits do not need to be addressed, those are just me stating my opinions on some pieces of code.

Comment on lines +62 to +64
baseURL={loris.BaseURL}
moduleURL={loris.BaseURL + '/redcap'}
hasPermission={loris.userHasPermission}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about passing these values as props to the module.

  • The first two can be obtained from the loris instance, no need to use props IMO.
  • The latter one is not used right now (but I guess that may change).

baseURL: props.baseURL,
data: {},
error: false,
isLoaded: false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just use data !== null instead of isLoaded ?


return (
<div>
{this.state.data == null
Copy link
Contributor

@MaximeBICMTL MaximeBICMTL Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this.state.data can ever be null, it is initialized with an empty object {} or a JSON received from the back-end. I would also avoid loose equality in our code (use === instead of ==).

super(props);

this.state = {
baseURL: props.baseURL,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would avoid putting constant data in a component state, I would rather use loris.BaseURL directly.

Comment on lines +19 to +25
this.state = {
baseURL: props.baseURL,
moduleURL: props.moduleURL,
data: {},
error: false,
isLoaded: false,
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments about constant data in state and isLoaded.

* @return {*} a formatted table cell for a given column
*/
formatColumn(column, cell, rowData, rowHeaders) {
let result = (<td>{cell}</td>);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use return directly in the match switch instead of putting things in result, using break, and then returning.

Comment on lines +132 to +133
// The fields configured for display/hide.
let fields = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about constant data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Instruments PR or issue related instruments Area: UI PR or issue related to the user interface Category: Feature PR or issue that aims to introduce a new feature Language: Javascript PR or issue that update Javascript code Language: PHP PR or issue that update PHP code Language: SQL PR or issue that update SQL code Module: redcap PR or issue related to redcap module Proposal PR or issue suggesting an improvement that can be accepted, rejected or altered RaisinBread PR or issue introducing/requiring improvements to the Raidinbread dataset Release: SQL patch PR that contains an SQL patch to apply

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants