Skip to content

Commit

Permalink
🐛 Strip '.dev' before checking semver
Browse files Browse the repository at this point in the history
  • Loading branch information
shnizzedy committed Aug 30, 2022
1 parent 2eadc9f commit 5ad6968
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 114 deletions.
189 changes: 75 additions & 114 deletions app/components/PipelineCard.jsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,50 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter, Link } from 'react-router-dom';
import { withRouter } from 'react-router-dom';
import Immutable from 'immutable';
import PropTypes from 'prop-types';
import semver from 'semver';

import clsx from 'clsx'
import { formatMs, withStyles } from '@material-ui/core/styles';
import { withStyles } from '@material-ui/core/styles';

import { Map } from 'immutable';

import Grid from '@material-ui/core/Grid';

import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import CardMedia from '@material-ui/core/CardMedia';
import CardContent from '@material-ui/core/CardContent';
import CardActions from '@material-ui/core/CardActions';

import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';

import Typography from '@material-ui/core/Typography';
import Avatar from '@material-ui/core/Avatar';
import IconButton from '@material-ui/core/IconButton';
import Button from '@material-ui/core/Button';
import Tooltip from '@material-ui/core/Tooltip';

import {
EnvironmentIcon,
PipelineIcon,
PipelineStepIcon,
PipelineExecutionTimeIcon,
SubjectIcon,
RunIcon,
LaunchIcon,
SettingsIcon,
NavigateNextIcon,
PlayArrowIcon,
TimerIcon,
LogIcon,
BrainIcon,
DeleteIcon,
DeprecatedIcon,
DownloadIcon,
DuplicateIcon
} from './icons';
import { formatLabel } from '../containers/pipeline/parts/PipelinePart';
import { isADefault } from '../containers/PipelinePage';
import PipelineStep from './PipelineStep';

import cpac from '@internal/c-pac';

const cardSteps = ['anatomical_preproc', 'functional_preproc', 'surface_analysis'];

/** A card component to show a pipeline configuration available to view/edit, duplicate, and/or delete. */
function stripDevSuffix(version) {
return version.endsWith('.dev') ? version.slice(0, -4) : version;
}

/** A card component to show a pipeline configuration available to view/edit, duplicate, and/or
* delete. */
class PipelineCard extends Component {
static propTypes = {
/** Inherited style */
Expand Down Expand Up @@ -100,36 +88,36 @@ class PipelineCard extends Component {
const configuration = pipeline.getIn(['versions', version, 'configuration']);
const cpacVersion = pipeline.getIn(['versions', version, 'version']);

var blob = new Blob(
const blob = new Blob(
[cpac.pipeline.dump(
configuration.toJS(), pipelineName, version, cpacVersion
)],
{ type: "text/yaml;charset=utf-8" }
{ type: 'text/yaml;charset=utf-8' }
);

var anchor = document.createElement('a');
const anchor = document.createElement('a');
anchor.href = window.URL.createObjectURL(blob);
anchor.target = '_blank';
anchor.download = pipelineName + '.yml'
anchor.download = `${pipelineName}.yml`;
anchor.click();
}

handleOpen = (pipeline) => {
this.props.history.push(`/pipelines/${pipeline}`)
this.props.history.push(`/pipelines/${pipeline}`);
}

render() {
const { classes, pipeline } = this.props
const { classes, pipeline } = this.props;

const pipelineIsADefault = isADefault(pipeline.get('id'));
let versionId = '0'
const versions = pipeline.get('versions')
if (!versions.has("0")) {
versionId = versions.keySeq().max()
let versionId = '0';
const versions = pipeline.get('versions');
if (!versions.has('0')) {
versionId = versions.keySeq().max();
}

const version = versions.get(versionId)
const configuration = version.getIn(['configuration', ]);
const version = versions.get(versionId);
const configuration = version.getIn(['configuration']);

let derivatives = [];
Object.keys(configuration.toJS()).forEach(step => {
Expand All @@ -138,59 +126,59 @@ class PipelineCard extends Component {
} else {
const tabStep = configuration.getIn([step]);
if (Map.isMap(tabStep)) {
let [...stepKeys] = tabStep.keys();
const [...stepKeys] = tabStep.keys();
if (stepKeys.includes('run')) {
const runswitch = configuration.getIn([step, 'run']);
if (
!cardSteps.includes(step) &&
runswitch &&
(
typeof(runswitch) === 'boolean' ||
(Array.isArray(runswitch) && runswitch.includes(true))
!cardSteps.includes(step)
&& runswitch
&& (
typeof runswitch === 'boolean'
|| (Array.isArray(runswitch) && runswitch.includes(true))
)
) { derivatives.push(step); }
}
} else {
console.warn(`Tab "${step}" seems to be malformed in pipeline "${pipeline.get('name')}"`);
}
}
})
});
derivatives = Array.from(derivatives);
derivatives = derivatives ? derivatives.length : 0;
let cardSubheader = `C-PAC ${version.get('version')}`;
if (configuration.hasOwnProperty('importedPipeline')) {
cardSubheader = `FROM '${configuration.importedPipeline}' (${cardSubheader})`
if (Object.prototype.hasOwnProperty.call(configuration, 'importedPipeline')) {
cardSubheader = `FROM '${configuration.importedPipeline}' (${cardSubheader})`;
}
if (semver.gte(version.get('version'), '1.8.0')) {
if (semver.gte(stripDevSuffix(version.get('version')), '1.8.0')) {
return (
<Card className={classes.card}>
<CardHeader
avatar={
avatar={(
<Avatar className={classes.avatar}>
<PipelineIcon />
</Avatar>
}
)}
title={pipeline.get('name')}
subheader={cardSubheader}
/>
<CardContent className={classes.info}>
<List>
{cardSteps.map(step =>{
{cardSteps.map(step => {
const runKey = 'run';
return (
<PipelineStep
{...{classes}}
{...{ classes }}
stepKey={configuration.getIn([step, runKey], true)}
label={formatLabel(step)}
key={step}
/>
)
);
})}
<PipelineStep
{...{classes}}
{...{ classes }}
stepKey={Boolean(derivatives)}
label={`${derivatives} derivative${derivatives === 1 ? '' : 's'}`}
key='derivatives'
key="derivatives"
/>
</List>
</CardContent>
Expand All @@ -202,14 +190,13 @@ class PipelineCard extends Component {
</IconButton>
</Tooltip>

{ !pipelineIsADefault ?
{ !pipelineIsADefault ? (
<Tooltip title="Delete">
<IconButton onClick={() => this.props.onDelete(pipeline.get('id'))}>
<DeleteIcon />
</IconButton>
</Tooltip>
: null
}
) : null }

<Tooltip title={pipelineIsADefault ? 'View' : 'View / Edit'}>
<IconButton className={classes.expand} onClick={() => this.handleOpen(pipeline.get('id'))}>
Expand All @@ -218,74 +205,48 @@ class PipelineCard extends Component {
</Tooltip>
</CardActions>
</Card>
)
} else {
return (
<Card className={classes.card}>
<CardHeader
avatar={
<Avatar className={classes.avatar}>
<PipelineIcon />
</Avatar>
}
title={pipeline.get('name')}
subheader={cardSubheader}
/>
<CardContent className={classes.info}>
);
}
return (
<Card className={classes.card}>
<CardHeader
avatar={(
<Avatar className={classes.avatar}>
<PipelineIcon />
</Avatar>
)}
title={pipeline.get('name')}
subheader={cardSubheader}
/>
<CardContent className={classes.info}>
<List>
<ListItem key='deprecated'>
<ListItem key="deprecated">
<ListItemIcon>
<DeprecatedIcon />
</ListItemIcon>
<ListItemText primary='Deprecated' secondary='Please upgrade your pipeline configuration' />
<ListItemText primary="Deprecated" secondary="Please upgrade your pipeline configuration" />
</ListItem>
</List>
</CardContent>
<CardActions className={classes.actions}>

<Tooltip title="Download config file">
<IconButton onClick={() => this.handleDownload(pipeline.get('id'))}>
<DownloadIcon />
</IconButton>
</Tooltip>

<Tooltip title="Delete">
<IconButton onClick={() => this.props.onDelete(pipeline.get('id'))}>
<DeleteIcon />
</IconButton>
</Tooltip>

</CardActions>
</Card>
)
};
}
}

/** A row to indicate s broad pipeline step on a pipeline card */
class PipelineStep extends Component {
static propTypes = {
/** Whether the step is On in the pipeline configuration */
stepKey: PropTypes.bool.isRequired,
/** Text to display for step */
label: PropTypes.string,
/** Inherited style */
classes: PropTypes.object
}

render() {
const { stepKey, label, classes } = this.props;
const enabledStyle = {root: stepKey ? classes.featEnabled : classes.featDisabled};
return (
<ListItem key={`step-${label}`}>
<ListItemIcon>
<PipelineStepIcon classes={enabledStyle} />
</ListItemIcon>
<ListItemText classes={enabledStyle} primary={label} />
</ListItem>
)
</CardContent>
<CardActions className={classes.actions}>

<Tooltip title="Download config file">
<IconButton onClick={() => this.handleDownload(pipeline.get('id'))}>
<DownloadIcon />
</IconButton>
</Tooltip>

<Tooltip title="Delete">
<IconButton onClick={() => this.props.onDelete(pipeline.get('id'))}>
<DeleteIcon />
</IconButton>
</Tooltip>

</CardActions>
</Card>
);
}
}

export default withRouter(withStyles(PipelineCard.styles)(PipelineCard));
export { cardSteps };
export { cardSteps };
32 changes: 32 additions & 0 deletions app/components/PipelineStep.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/** A row to indicate a broad pipeline step on a pipeline card */
import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { ListItem, ListItemIcon, ListItemText } from '@material-ui/core';
import { PipelineStepIcon } from './icons';

class PipelineStep extends Component {
static propTypes = {
/** Whether the step is On in the pipeline configuration */
stepKey: PropTypes.bool.isRequired,
/** Text to display for step */
label: PropTypes.string,
/** Inherited style */
classes: PropTypes.object
}

render() {
const { stepKey, label, classes } = this.props;
const enabledStyle = {root: stepKey ? classes.featEnabled : classes.featDisabled};
return (
<ListItem key={`step-${label}`}>
<ListItemIcon>
<PipelineStepIcon classes={enabledStyle} />
</ListItemIcon>
<ListItemText classes={enabledStyle} primary={label} />
</ListItem>
);
}
}

export default PipelineStep;

0 comments on commit 5ad6968

Please sign in to comment.