Skip to content

Commit

Permalink
Merge pull request #203 from MetaCell/sdsv-7
Browse files Browse the repository at this point in the history
Sdsv 7 - Expand Dataset Metadata
  • Loading branch information
jrmartin authored Jan 11, 2024
2 parents d135da2 + ea783bc commit 5ecdb43
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 266 deletions.
150 changes: 25 additions & 125 deletions src/components/NodeDetailView/Details/DatasetDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,142 +10,42 @@ import SimpleLinkedChip from './Views/SimpleLinkedChip';
import USER from "../../../images/user.svg";
import SimpleLabelValue from './Views/SimpleLabelValue';
import { detailsLabel } from '../../../constants';
import { rdfTypes } from "../../../utils/graphModel";
import { isValidUrl } from './utils';

const DatasetDetails = (props) => {
const { node } = props;
const nodes = window.datasets[node.dataset_id].splinter.nodes;

let title = "";
let label = "";
let idDetails = "";
let description = "";
// both tree and graph nodes are present, extract data from both
if (node?.tree_node && node?.graph_node) {
idDetails = node.graph_node?.id + detailsLabel;
label = node?.graph_node.attributes?.label?.[0];
title = node?.graph_node.attributes?.title?.[0];
description = node?.graph_node.attributes?.description?.[0];
// the below is the case where we have data only from the tree/hierarchy
} else if (node?.tree_node) {
label = node?.tree_node?.basename;
idDetails = node?.tree_node?.id + detailsLabel;
// the below is the case where we have data only from the graph
} else {
idDetails = node.graph_node?.id + detailsLabel;
label = node.graph_node?.attributes?.label?.[0];
}

let latestUpdate = "Not defined."
if (node?.graph_node?.attributes?.latestUpdate !== undefined) {
latestUpdate = new Date(node.graph_node.attributes?.latestUpdate?.[0])
}

let contactPerson = [];
if (node.graph_node.attributes?.hasResponsiblePrincipalInvestigator !== undefined) {
node.graph_node.attributes?.hasResponsiblePrincipalInvestigator.map(user => {
const contributor = nodes.get(user);
contactPerson.push({
name: contributor?.name,
designation: 'Principal Investigator',
img: USER
});
return user;
});
}

if (node.graph_node.attributes?.hasContactPerson !== undefined) {
node.graph_node.attributes?.hasContactPerson.map(user => {
const contributor = nodes.get(user);
contactPerson.push({
name: contributor?.name,
designation: 'Contributor',
img: USER
});
return user;
});
}

const DETAILS_LIST = [
{
title: 'Error Index',
value: node.graph_node.attributes?.errorIndex
},
{
title: 'Template Schema Version',
value: node.graph_node.attributes?.hasDatasetTemplateSchemaVersion
},
{
title: 'Experiment Modality',
value: node.graph_node.attributes?.hasExperimentalModality
}
];
let datasetPropertiesModel = [...rdfTypes["Dataset"].properties];

return (
<Box id={idDetails}>

<Box id={node.graph_node?.id + detailsLabel}>
<Box className="tab-content">
<SimpleLabelValue label={'Title'} value={title} heading={'Dataset Details'} />
{ node.graph_node.attributes?.hasDoi && node.graph_node.attributes?.hasDoi?.[0] !== ""
? (<Box className="tab-content-row">
<Typography component="label">Label</Typography>
<Links key={`label_href_link`} href={node.graph_node.attributes?.hasDoi?.[0]} title={label} />
</Box>)
: (<SimpleLabelValue label={'Label'} value={label} />)
}
<SimpleLabelValue label={'Description'} value={description} />

<SimpleLabelValue label={'Updated On'} value={latestUpdate.toString()} />

<Box className="tab-content-row">
<Typography component="label">About</Typography>
<SimpleLinkedChip chips={node.graph_node.attributes?.isAbout} />
</Box>

<Box className="tab-content-row">
<Typography component="label">Protocol Techniques</Typography>
<SimpleLinkedChip chips={node.graph_node.attributes?.protocolEmploysTechnique} />
</Box>
{datasetPropertiesModel?.map( property => {
if ( property.visible ){
const propValue = node.graph_node.attributes[property.property]?.[0];
if ( isValidUrl(propValue) ){
return (<Box className="tab-content-row">
<Typography component="label">{property.label}</Typography>
<Links key={`detail_links_dataset`} href={propValue} title={property.label + " Link"} />
</Box>)
}

<Box className="tab-content-row">
<List component="nav" aria-label="main">
{
DETAILS_LIST?.map((item, index) => (
<ListItemText key={`detail_list_${index}`}>
<Typography component="label">{item?.title}</Typography>
<Typography>{item?.value}</Typography>
</ListItemText>
))
if ( typeof propValue === "object" ){
return (<Box className="tab-content-row">
<Typography component="label">{property.label}</Typography>
<SimpleLinkedChip chips={node.graph_node.attributes[property.property]} />
</Box>)
}
</List>
</Box>

{ node.graph_node.attributes?.hasExperimentalApproach !== undefined
? (<SimpleLabelValue label={'Experimental Approach'} value={node.graph_node.attributes?.hasExperimentalApproach?.toString()} />
)
: <> </>
}
if ( typeof propValue === "string" ){
return (<SimpleLabelValue label={property.label} value={propValue} />)
}

{ node.graph_node.attributes?.hasDoi !== undefined
? (<Box className="tab-content-row">
<Typography component="label">Links</Typography>
<Links key={`detail_links_dataset`} href={node.graph_node.attributes?.hasDoi?.[0]} title="Dataset" />
</Box>)
: <> </>
}
{ node.graph_node.attributes?.hasAdditionalFundingInformation !== undefined
? (<SimpleLabelValue label={'Additional Funding Information'} value={node.graph_node.attributes?.hasAdditionalFundingInformation} />
)
: <> </>
}
{ node.graph_node.attributes?.statusOnPlatform !== undefined
? (<SimpleLabelValue label={'Status on Platform'} value={node.graph_node.attributes?.statusOnPlatform} />
)
: <> </>
}
{ node.graph_node.attributes?.hasLicense !== undefined
? (<SimpleLabelValue label={'License'} value={node.graph_node.attributes?.hasLicense} />
)
: <> </>
}
return (<> </>)
}
})}
</Box>
</Box>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/NodeDetailView/Details/GroupDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const GroupDetails = (props) => {
return (
<Box className="secondary-sidebar_body" id={idDetails}>
<Box className="tab-content">
<SimpleLabelValue label={'# of Subjects '} value={node?.graph_node?.subjects} heading={node?.graph_node?.name + ' group details'} />
<SimpleLabelValue label={'# of Subjects '} value={node?.graph_node?.subjects} heading={node?.graph_node?.name} />
</Box>
</Box>
);
Expand Down
25 changes: 2 additions & 23 deletions src/components/NodeDetailView/Details/SubjectDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,6 @@ const SubjectDetails = (props) => {
title = node.tree_node.basename;
}

const DETAILS_LIST = [
{
title: 'Weight Unit',
value: node.graph_node.attributes?.weightUnit
},
{
title: 'Weight Value',
value: node.graph_node.attributes?.weightValue
}
];

const getGroupNode = (groupName, node)=> {
let n = node.graph_node.parent;
let match = false;
Expand All @@ -57,19 +46,9 @@ const SubjectDetails = (props) => {
}

return (
<Box id={idDetails}>
<Box id={node?.graph_node?.id + detailsLabel}>
<Box className="tab-content">
{ node.graph_node.attributes?.hasUriHuman && node.graph_node.attributes?.hasUriHuman[0] !== ""
? (<Box className="tab-content-row">
<Typography component="h3">{"Subject Details"}</Typography>
<Typography component="label">Label</Typography>
<Links key={`label_href_link`} href={node.graph_node.attributes?.hasUriHuman[0]} title={title} />
</Box>)
: (( <Box className="tab-content-row">
<Typography component="label">Subject Details</Typography>
<SimpleLinkedChip chips={[{ value : title}]} node={node.graph_node} />
</Box>))
}
<SimpleLabelValue label={""} value={""} heading={title} />

{ node.graph_node?.attributes?.publishedURI && node.graph_node?.attributes?.publishedURI !== ""
? (<Box className="tab-content-row">
Expand Down
10 changes: 10 additions & 0 deletions src/components/NodeDetailView/Details/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,13 @@ export const simpleValue = (label, value) => {
return (<> </>);
}
}

export const isValidUrl = (urlString) => {
var urlPattern = new RegExp('^(https?:\\/\\/)?' + // validate protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // validate OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
'(\\#[-a-z\\d_]*)?$', 'i'); // validate fragment locator
return !!urlPattern.test(urlString);
}
97 changes: 30 additions & 67 deletions src/components/NodeDetailView/NodeDetailView.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React from "react";
import { Box } from "@material-ui/core";
import NodeFooter from "./Footers/Footer";
import DetailsFactory from './factory';
import { useSelector } from 'react-redux'
import Breadcrumbs from "./Details/Views/Breadcrumbs";
import { IconButton, Tooltip, Link } from '@material-ui/core';
import HelpIcon from '@material-ui/icons/Help';
import { subject_key, protocols_key, contributors_key } from '../../constants';
import config from "./../../config/app.json";

const NodeDetailView = (props) => {
var otherDetails = undefined;
Expand All @@ -22,71 +18,38 @@ const NodeDetailView = (props) => {
}
};
var path = []
if (nodeSelected?.tree_node?.path !== undefined && nodeSelected?.tree_node !== null) {
path = [...nodeSelected.tree_node.path]
path.shift();
otherDetails = path.reverse().map( singleNode => {
const tree_node = window.datasets[nodeSelected.dataset_id].splinter.tree_map.get(singleNode);
const new_node = {
dataset_id: nodeSelected.dataset_id,
graph_node: tree_node.graph_reference,
tree_node: tree_node
}
// I don't like the check on primary and derivative below since this depends on the data
// but it's coming as a feature request, so I guess it can stay there.
if (new_node.tree_node.id !== subject_key
&& new_node.tree_node.id !== contributors_key
&& new_node.tree_node.id !== protocols_key
&& new_node.tree_node.basename !== 'primary'
&& new_node.tree_node.basename !== 'derivative') {
links.pages.push({
id: singleNode,
title: tree_node.text,
href: '#'
});
return factory.createDetails(new_node).getDetail()
}
return <> </>;
});
links.current = {
id: nodeSelected.tree_node.id,
text: nodeSelected.tree_node.text
};
} else {
path = [];
var latestNodeVisited = nodeSelected;
while ( latestNodeVisited.graph_node.parent !== undefined ) {
path.push(latestNodeVisited.graph_node.parent.id);
latestNodeVisited = {
tree_node: undefined,
graph_node: latestNodeVisited.graph_node.parent
};
var latestNodeVisited = nodeSelected;
while ( latestNodeVisited.graph_node.parent !== undefined ) {
path.push(latestNodeVisited.graph_node.parent.id);
latestNodeVisited = {
tree_node: undefined,
graph_node: latestNodeVisited.graph_node.parent
};
};

otherDetails = path.reverse().map( singleNode => {
const graph_node = window.datasets[nodeSelected.dataset_id].splinter.nodes.get(singleNode);
const new_node = {
dataset_id: nodeSelected.dataset_id,
graph_node: graph_node,
tree_node: graph_node.tree_reference
}
if (new_node.graph_node.id !== subject_key
&& new_node.graph_node.id !== contributors_key
&& new_node.graph_node.id !== protocols_key) {
links.pages.push({
id: singleNode,
title: graph_node.name,
href: '#'
});
return factory.createDetails(new_node).getDetail()
}
return <> </>;
});
links.current = {
id: nodeSelected.graph_node.id,
text: nodeSelected.graph_node.name
};
}
otherDetails = path.reverse().map( singleNode => {
const graph_node = window.datasets[nodeSelected.dataset_id].splinter.nodes.get(singleNode);
const new_node = {
dataset_id: nodeSelected.dataset_id,
graph_node: graph_node,
tree_node: graph_node.tree_reference
}
if (new_node.graph_node.id !== subject_key
&& new_node.graph_node.id !== contributors_key
&& new_node.graph_node.id !== protocols_key) {
links.pages.push({
id: singleNode,
title: graph_node.name,
href: '#'
});
return factory.createDetails(new_node).getDetail()
}
return <> </>;
});
links.current = {
id: nodeSelected.graph_node.id,
text: nodeSelected.graph_node.name
};

return (
<Box className={"secondary-sidebar" + (props.open ? " in" : "")}>
Expand Down
Loading

0 comments on commit 5ecdb43

Please sign in to comment.