diff --git a/src/ProgressWorkflow.jsx b/src/ProgressWorkflow.jsx index ec085d3..287e14f 100644 --- a/src/ProgressWorkflow.jsx +++ b/src/ProgressWorkflow.jsx @@ -1,7 +1,8 @@ import PropTypes from 'prop-types'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Portal } from 'react-portal'; import { useDispatch, useSelector } from 'react-redux'; +import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib'; import { getWorkflowProgress } from './actions'; import './less/editor.less'; @@ -18,9 +19,14 @@ const ProgressWorkflow = (props) => { const [workflowProgressSteps, setWorkflowProgressSteps] = useState([]); const [currentState, setCurrentState] = useState(null); const workflowProgress = useSelector((state) => state?.workflowProgress); + const pusherRef = useRef(null); - // toggle progress component visible by clicking on the button - const setVisibleSide = () => { + // set visible by clicking oustisde + const setVisibleSide = (isVisible) => { + setVisible(isVisible); + }; + // toggle visible by clicking on the button + const toggleVisibleSide = () => { setVisible(!visible); }; @@ -65,6 +71,18 @@ const ProgressWorkflow = (props) => { dispatch(getWorkflowProgress(pathname)); // the are paths that don't have workflow (home, login etc) }, [dispatch, pathname, content]); + // on mount subscribe to mousedown to be able to close on click outside + useEffect(() => { + const handleClickOutside = (e) => { + if (pusherRef.current && doesNodeContainClick(pusherRef.current, e)) + return; + + setVisibleSide(false); + }; + + document.addEventListener('mousedown', handleClickOutside, false); + }, []); + const itemTracker = (tracker) => (
  • { > {currentState ? ( <> -
    +
    diff --git a/src/ProgressWorkflow.test.jsx b/src/ProgressWorkflow.test.jsx new file mode 100644 index 0000000..213d6ff --- /dev/null +++ b/src/ProgressWorkflow.test.jsx @@ -0,0 +1,165 @@ +// ✓ ca nu crapa la obiect gol +// ca nu crapa fara procent +// daca vine cum trebuie vedem procent, titlu, sidebar progress tracker +// ca nu face nimic daca nu e pe ce ruta trebuie +// ca nu face nimic daca nu e logat userul +// ca nu face nimic daca nu exista toolbar + +import React from 'react'; +import { Provider } from 'react-intl-redux'; +import { MemoryRouter } from 'react-router-dom'; +import renderer from 'react-test-renderer'; +import configureStore from 'redux-mock-store'; +import ProgressWorkflow from './ProgressWorkflow'; + +const mockStore = configureStore(); +const props = { content: { review_state: 'pending' }, pathname: '/' }; +const propsEmpty = {}; + +describe('ProgressWorkflow', () => { + it('renders the ProgressWorkflow component without breaking if props and workflow are empty', () => { + const store = mockStore({ + intl: { + locale: 'en', + messages: {}, + }, + workflowProgress: {}, + }); + const component = renderer.create( + + + + + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); + + it('renders the ProgressWorkflow component', () => { + const store = mockStore({ + intl: { + locale: 'en', + messages: {}, + }, + workflowProgress: { + '@id': 'http://localhost:3000/api/my-page/@workflow.progress', + done: 50, + steps: [ + [ + ['private'], + 25, + ['Private'], + ['Can only be seen and edited by the owner.'], + ], + [ + ['pending'], + 50, + ['Pending review'], + ['Waiting to be reviewed, not editable by the owner.'], + ], + [ + ['review_one', 'review_two', 'review_three', 'review_four'], + 75, + [ + 'Review One: Technical', + 'Review two: Head of Technical', + 'Review three: Head of Department', + 'Review Four: CTO', + ], + [ + 'Review One: Technical', + 'Review by Head of Tech Depart', + 'Review by Head of Department', + 'Review by CTO', + ], + ], + [ + ['published', 'visible'], + 100, + ['Published', 'Public draft'], + [ + 'Visible to everyone, not editable by the owner.', + 'Visible to everyone, but not approved by the reviewers.', + ], + ], + ], + }, + }); + const component = renderer.create( + + + + + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); + + it('renders the ProgressWorkflow component with Percent showing correct value', () => { + const store = mockStore({ + intl: { + locale: 'en', + messages: {}, + }, + workflowProgress: { + '@id': 'http://localhost:3000/api/my-page/@workflow.progress', + done: 50, + steps: [ + [ + ['private'], + 25, + ['Private'], + ['Can only be seen and edited by the owner.'], + ], + [ + ['pending'], + 50, + ['Pending review'], + ['Waiting to be reviewed, not editable by the owner.'], + ], + [ + ['review_one', 'review_two', 'review_three', 'review_four'], + 75, + [ + 'Review One: Technical', + 'Review two: Head of Technical', + 'Review three: Head of Department', + 'Review Four: CTO', + ], + [ + 'Review One: Technical', + 'Review by Head of Tech Depart', + 'Review by Head of Department', + 'Review by CTO', + ], + ], + [ + ['published', 'visible'], + 100, + ['Published', 'Public draft'], + [ + 'Visible to everyone, not editable by the owner.', + 'Visible to everyone, but not approved by the reviewers.', + ], + ], + ], + }, + }); + const component = renderer.create( + + + + + , + ); + + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); +}); diff --git a/src/__snapshots__/ProgressWorkflow.test.jsx.snap b/src/__snapshots__/ProgressWorkflow.test.jsx.snap new file mode 100644 index 0000000..dd1bf75 --- /dev/null +++ b/src/__snapshots__/ProgressWorkflow.test.jsx.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ProgressWorkflow renders the ProgressWorkflow component 1`] = `null`; + +exports[`ProgressWorkflow renders the ProgressWorkflow component with Percent showing correct value 1`] = `null`; + +exports[`ProgressWorkflow renders the ProgressWorkflow component without breaking if props and workflow are empty 1`] = `null`;