Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class VwbAdminQueryServiceImpl implements VwbAdminQueryService {
+ " w.created_by_email, \n"
+ " w.created_date, \n"
+ " w.gcp_project_id, \n"
+ " w.workspace_metadata_policy, \n"
+ " p.billing_account_id, \n"
+ "FROM \n"
+ " %s w \n"
Expand Down Expand Up @@ -72,6 +73,7 @@ public class VwbAdminQueryServiceImpl implements VwbAdminQueryService {
+ " w.created_by_email, \n"
+ " w.created_date, \n"
+ " w.gcp_project_id, \n"
+ " w.workspace_metadata_policy, \n"
+ " p.billing_account_id, \n"
+ "FROM \n"
+ " %s w \n"
Expand Down Expand Up @@ -254,6 +256,8 @@ private VwbWorkspace fieldValueListToVwbWorkspace(FieldValueList row) {
FieldValues.getString(row, "description").ifPresent(vwbWorkspace::setDescription);
FieldValues.getString(row, "created_by_email").ifPresent(vwbWorkspace::setCreatedBy);
FieldValues.getString(row, "gcp_project_id").ifPresent(vwbWorkspace::setGoogleProjectId);
FieldValues.getString(row, "workspace_metadata_policy")
.ifPresent(vwbWorkspace::setResearchPurpose);
FieldValues.getString(row, "billing_account_id").ifPresent(vwbWorkspace::billingAccountId);

FieldValues.getDateTime(row, "created_date")
Expand Down
3 changes: 3 additions & 0 deletions api/src/main/resources/workbench-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13757,6 +13757,9 @@ components:
description:
type: string
description: The description of the workspace
researchPurpose:
type: string
description: JSON string containing all research purpose description data
createdBy:
type: string
description: Username of the workspace creator
Expand Down
152 changes: 152 additions & 0 deletions ui/src/app/pages/admin/vwb/admin-vwb-workspace.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import * as fp from 'lodash/fp';
import { Accordion, AccordionTab } from 'primereact/accordion';
import { Column } from 'primereact/column';
import { DataTable } from 'primereact/datatable';

Expand All @@ -14,10 +15,84 @@ import {
import { Error as ErrorDiv } from 'app/components/inputs';
import { Spinner, SpinnerOverlay } from 'app/components/spinners';
import { WithSpinnerOverlayProps } from 'app/components/with-spinner-overlay';
import { RESEARCH_PURPOSE_MAPPING } from 'app/pages/admin/vwb/vwb-research-purpose-text';
import { WorkspaceInfoField } from 'app/pages/admin/workspace/workspace-info-field';
import { vwbWorkspaceAdminApi } from 'app/services/swagger-fetch-clients';
import colors, { colorWithWhiteness } from 'app/styles/colors';
import { reactStyles } from 'app/utils';
import { MatchParams, serverConfigStore } from 'app/utils/stores';

const styles = reactStyles({
editIcon: {
marginTop: '0.15rem',
height: 22,
width: 22,
fill: colors.light,
backgroundColor: colors.accent,
padding: '5px',
borderRadius: '23px',
},
mainHeader: {
fontSize: '18px',
fontWeight: 600,
color: colors.primary,
marginBottom: '0.75rem',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
},
sectionContentContainer: {
marginLeft: '1.5rem',
},
sectionHeader: {
fontSize: '16px',
fontWeight: 600,
color: colors.primary,
marginTop: '1.5rem',
},
sectionItemWithBackground: {
padding: '10px',
backgroundColor: 'transparent',
color: colors.primary,
marginLeft: '0.75rem',
borderRadius: '3px',
},
sectionSubHeader: {
fontSize: '14px',
fontWeight: 600,
color: colors.primary,
marginTop: '0.75rem',
},
subSectionText: {
fontSize: '14px',
fontWeight: 400,
color: colors.primary,
lineHeight: '22px',
},
sectionText: {
fontSize: '14px',
lineHeight: '24px',
color: colors.primary,
marginTop: '0.45rem',
},
reviewPurposeReminder: {
marginTop: '0.45rem',
borderStyle: 'solid',
height: '3.75rem',
color: colors.primary,
alignItems: 'center',
justifyContent: 'center',
borderColor: colors.warning,
borderRadius: '0.6rem',
borderWidth: '0.15rem',
backgroundColor: colorWithWhiteness(colors.highlight, 0.7),
},
});

interface ResearchPurposeItem {
[key: string]: boolean | string;
}

const collabList = (users: UserRole[]) => {
return users?.length > 0
? users.map((c) => (
Expand All @@ -41,6 +116,7 @@ export const AdminVwbWorkspace = fp.flow(withRouter)((props: Props) => {
const [loadingWorkspaceActivity, setLoadingWorkspaceActivity] =
useState<boolean>(false);
const [dataLoadError, setDataLoadError] = useState<Response>();
const [researchPurpose, setResearchPurpose] = useState<ResearchPurposeItem>();

const handleDataLoadError = async (error) => {
if (error instanceof Response) {
Expand All @@ -66,13 +142,32 @@ export const AdminVwbWorkspace = fp.flow(withRouter)((props: Props) => {
vwbWorkspaceAdminApi()
.getVwbWorkspaceAdminView(ufid)
.then((resp) => {
const test = JSON.parse(resp.workspace.researchPurpose);
console.log(test);
console.log(typeof test[0].form_data.fitNone);
console.log(typeof test[0].form_data.populationYesNo);
setWorkspaceDetails(resp);
setResearchPurpose(
(JSON.parse(resp.workspace.researchPurpose)?.[0]
?.form_data as ResearchPurposeItem) ?? {}
);
getWorkspaceActivity(resp.workspace.id);
})
.catch((error) => handleDataLoadError(error))
.finally(() => setLoadingWorkspace(false));
};

const displayResearchPurposeItem = (item) => {
switch (typeof researchPurpose[item.field]) {
case 'boolean':
return item.valueField ? researchPurpose[item.valueField] : item.value;
case 'string':
return researchPurpose[item.field];
default:
return '';
}
};

useEffect(() => {
props.hideSpinner();
}, []);
Expand Down Expand Up @@ -120,6 +215,63 @@ export const AdminVwbWorkspace = fp.flow(withRouter)((props: Props) => {
<WorkspaceInfoField labelText='Description'>
{workspace.description}
</WorkspaceInfoField>
<Accordion>
<AccordionTab header='Research Purpose'>
{RESEARCH_PURPOSE_MAPPING.map((section, s) => (
<div key={s}>
<div style={styles.sectionHeader}>
{section.sectionHeader}
</div>
<div style={styles.sectionContentContainer}>
{section.items.some(
(item) => !!researchPurpose?.[item.field]
) &&
section.items.map((item, i) =>
researchPurpose[item.field] ? (
<>
{item.title && (
<div style={styles.sectionSubHeader}>
{item.title}
</div>
)}
<div key={i}>
<div
style={{
marginTop: i > 0 ? '1.5rem' : '0.45rem',
marginLeft: '1.5rem',
}}
>
{displayResearchPurposeItem(item)}
</div>
</div>
{item.subItems?.some(
(subItem) => !!researchPurpose?.[subItem.field]
) &&
item.subItems?.map((subItem, si) =>
researchPurpose[subItem.field] ? (
<div
key={si}
style={styles.sectionContentContainer}
>
{subItem.title && (
<div style={styles.sectionSubHeader}>
{subItem.title}
</div>
)}
<div style={styles.subSectionText}>
{displayResearchPurposeItem(subItem)}
</div>
</div>
) : null
)}
</>
) : null
)}
</div>
</div>
))}
</AccordionTab>
</Accordion>
<h3>Collaborators</h3>
<div className='collaborators' style={{ marginTop: '1.5rem' }}>
<div style={{ marginBottom: '1rem' }}>
Expand Down
Loading