Skip to content

Commit

Permalink
Display Removed flag in protocols' steps (#941)
Browse files Browse the repository at this point in the history
* 4501

* bumping version

* Implementing the suggested text

* fixing linting error
  • Loading branch information
parvinba authored Sep 2, 2024
1 parent be01508 commit c4b4ca9
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 18 deletions.
3 changes: 2 additions & 1 deletion client/components/download-link/renderers/docx-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,8 @@ export default (application, sections, values, updateImageDimensions) => {

switch (name) {
case 'steps':
const [ steps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});
let [ steps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});
steps = steps.filter(step => !step.deleted);
return (steps || []).forEach((stepValues, index) => {
doc.createParagraph(`Step ${index + 1}${stepValues.reference ? `: ${stepValues.reference}` : ''} (${stepValues.optional ? 'optional' : 'mandatory'})`).heading4();
const repeatedFrom = getRepeatedFromProtocolIndex(stepValues, values.id);
Expand Down
4 changes: 3 additions & 1 deletion client/components/repeater.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ class Repeater extends Component {
return Promise.resolve()
.then(this.props.onBeforeRemove)
.then(() => {
if (this.props.softDelete) {
// mark record deleted, second check is to
// ensure that reusable step which was used to create reusable step in a protocol is not deleted, when deleting an instance of reusable step.
if (this.props.softDelete && !this.state.items[index].reusable) {
return this.update(this.state.items.map((item, i) => {
if (index === i) {
return { ...item, deleted: true };
Expand Down
33 changes: 33 additions & 0 deletions client/helpers/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,39 @@ export const hydrateSteps = (protocols, steps, reusableSteps) => {
return [hydratedSteps, Object.values(reusableSteps)];
};

export const removeNewDeleted = (steps, previousSteps) => {
let oldSteps = [];
previousSteps.forEach(protocol => {
protocol.forEach(step => oldSteps.push(step.id));
});
return (steps || []).filter(p => {
if (p.deleted === true) {
return !!oldSteps.includes(p.id);
}
return true;
});
};

export const addDeletedReusableSteps = (steps, previousSteps, reusableSteps) => {
let stepIds = [];
steps.forEach(step => {
stepIds.push(step.id);
});
let oldIndex = 0;
for (let i = 0; i < previousSteps.length; i++) {
if (stepIds.includes(previousSteps[i].id)) {
oldIndex = stepIds.indexOf(previousSteps[i].id);
} else {
oldIndex = oldIndex + 1;
const found = reusableSteps.find((reusableStep) => reusableStep.id === previousSteps[i].reusableStepId);
let step = {...found};
step.deleted = true;
steps.splice(oldIndex, 0, step);
}
}
return steps;
};

export const getTruncatedStepTitle = (step, numCharacters) => {
const title = getStepTitle(step.title, null);
if (!title || title.trim() === '') return null;
Expand Down
3 changes: 2 additions & 1 deletion client/pages/sections/granted/protocol-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ const Step = ({ id, index, fields, prefix, ...props }) => {
};

const Steps = ({ values, fields, pdf, prefix, project }) => {
const [ steps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});
let [ steps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});
steps = steps.filter(step => !step.deleted);

return (
<div className="granted-steps">
Expand Down
52 changes: 40 additions & 12 deletions client/pages/sections/protocols/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {
getRepeatedFromProtocolIndex,
getStepTitle,
getTruncatedStepTitle,
hydrateSteps
hydrateSteps,
removeNewDeleted,
addDeletedReusableSteps
} from '../../../helpers/steps';
import { saveReusableSteps } from '../../../actions/projects';
import Expandable from '../../../components/expandable';
Expand Down Expand Up @@ -46,7 +48,9 @@ class Step extends Component {
removeItem = e => {
e.preventDefault();
if (window.confirm('Are you sure you want to remove this step?')) {
this.scrollToPrevious();
if (!this.props.values.completed) {
this.setCompleted(true);
}
this.props.removeItem();
}
}
Expand Down Expand Up @@ -141,7 +145,8 @@ class Step extends Component {
pdf,
readonly,
expanded,
onToggleExpanded
onToggleExpanded,
number
} = this.props;
const changeFieldPrefix = values.reusableStepId ? `reusableSteps.${values.reusableStepId}.` : this.props.prefix;

Expand Down Expand Up @@ -224,15 +229,20 @@ class Step extends Component {

const repeatedFrom = getRepeatedFromProtocolIndex(values, protocol.id);
const step = <>
{
values.deleted && <span className="badge deleted">removed</span>
}
<section
className={classnames('step', { completed: !stepEditable, editable })}
ref={this.step}
>
<NewComments comments={relevantComments} />
<ChangedBadge fields={changeFields(values, changeFieldPrefix)} protocolId={protocol.id} />
{
!values.deleted && <ChangedBadge fields={changeFields(values, changeFieldPrefix)} protocolId={protocol.id} />
}
<Fragment>
{
editable && completed && !deleted && (
editable && completed && !deleted && !values.deleted && (
<div className="float-right">
{
length > 1 && (
Expand All @@ -246,7 +256,10 @@ class Step extends Component {
)
}
<h3>
{`Step ${index + 1}`}
Step { !values.deleted && number + 1 }
{
<a href="#" className={classnames('inline-block', { restore: values.deleted })} onClick={this.props.restoreItem}>{values.deleted ? ' Restore' : ''}</a>
}
{(pdf || readonly) && values.reference && (<Fragment>: { values.reference }</Fragment>)}
{
completed && !isUndefined(values.optional) &&
Expand All @@ -261,7 +274,7 @@ class Step extends Component {
}
</Fragment>
<EditStepWarning editingReusableStep={editingReusableStep} protocol={protocol} step={values} completed={completed}/>
{stepContent}
{!values.deleted && stepContent}
</section>
</>;

Expand Down Expand Up @@ -319,14 +332,20 @@ class Step extends Component {
return (
<section className={'review-step'}>
<NewComments comments={relevantComments} />
<ChangedBadge fields={changeFields(values, changeFieldPrefix)} protocolId={protocol.id} />
{
values.deleted && <span className="badge deleted">removed</span>
}
{
!values.deleted && <ChangedBadge fields={changeFields(values, changeFieldPrefix)} protocolId={protocol.id} />
}
<Expandable expanded={expanded} onHeaderClick={() => onToggleExpanded(index)}>
<Fragment>
<p className={'toggles float-right'}>
<Button className="link no-wrap" onClick={() => onToggleExpanded(index)}>{expanded ? 'Close' : 'Open'} step</Button>
</p>
{values.reference ? <h3 className={'title inline'}>{values.reference}</h3> : <h3 className={'title no-wrap'}>{getStepTitle(values.title)}</h3>}
<h4 className="light">Step {index + 1} {values.optional === true ? '(optional)' : '(mandatory)'}{repeatedFrom ? ` - repeated from protocol ${repeatedFrom}` : ''}</h4>
<h4
className="light">{values.deleted ? 'Removed step' : `Step ${number + 1}`} {values.optional === true ? '(optional)' : '(mandatory)'}{repeatedFrom ? ` - repeated from protocol ${repeatedFrom}` : ''}</h4>
</Fragment>
{stepContent}
</Expandable>
Expand All @@ -337,7 +356,7 @@ class Step extends Component {
}
}

const StepSelector = ({ reusableSteps, values, onSaveSelection, length, onCancel }) => {
const StepSelector = ({reusableSteps, values, onSaveSelection, length, onCancel}) => {
const DEFAULT_STEP_REFERENCE = 'Unnamed step';
const MAX_CHARACTERS_FROM_TITLE = 80;
const [selectedSteps, setSelectedSteps] = useState([]);
Expand Down Expand Up @@ -409,6 +428,7 @@ const StepsRepeater = ({ values, prefix, updateItem, editable, project, isReview
singular="step"
prefix={prefix}
items={steps}
softDelete={true}
onSave={steps => {
// Extract reusable steps to save
// Update reusableSteps on project only when they are complete, or have previously been saved
Expand Down Expand Up @@ -444,8 +464,16 @@ const StepsRepeater = ({ values, prefix, updateItem, editable, project, isReview

export default function Steps({project, values, ...props}) {
const isReviewStep = parseInt(useParams().step, 10) === 1;
const [ steps, reusableSteps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});

const [ allSteps, reusableSteps ] = hydrateSteps(project.protocols, values.steps, project.reusableSteps || {});
let steps = allSteps;
if (props.pdf) {
steps = allSteps.filter(step => !step.deleted);
} else {
steps = removeNewDeleted(allSteps, props.previousProtocols.steps);
if (!props.editable && props.previousProtocols.steps.length > props.index) {
steps = addDeletedReusableSteps(steps, props.previousProtocols.steps[props.index], reusableSteps);
}
}
const [expanded, setExpanded] = useState(steps.map(() => false));

const setAllExpanded = (e) => {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@asl/projects",
"version": "15.6.0",
"version": "15.6.1",
"description": "ASL PPL prototype",
"main": "client/external.js",
"styles": "assets/scss/projects.scss",
Expand Down

0 comments on commit c4b4ca9

Please sign in to comment.