workflow deprication flow 90/72390/2
authorStanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
Sun, 11 Nov 2018 12:02:21 +0000 (14:02 +0200)
committerAvi Gaffa <avi.gaffa@amdocs.com>
Tue, 20 Nov 2018 09:44:05 +0000 (09:44 +0000)
Issue-ID: SDC-1866
Change-Id: I48bd4e825492b6a5477eef28cef804c07fd90e14
Signed-off-by: Stanislav Vishnevetskiy <shlomo-stanisla.vishnevetskiy@amdocs.com>
39 files changed:
workflow-designer-ui/src/main/frontend/resources/scss/_components.scss
workflow-designer-ui/src/main/frontend/resources/scss/components/_archiveLabel.scss [new file with mode: 0644]
workflow-designer-ui/src/main/frontend/resources/scss/components/_versionController.scss
workflow-designer-ui/src/main/frontend/resources/scss/features/_catalog.scss
workflow-designer-ui/src/main/frontend/resources/scss/features/_overview.scss
workflow-designer-ui/src/main/frontend/src/features/catalog/Catalog.js
workflow-designer-ui/src/main/frontend/src/features/catalog/CatalogView.jsx
workflow-designer-ui/src/main/frontend/src/features/catalog/__tests__/catalogActions-test.js
workflow-designer-ui/src/main/frontend/src/features/catalog/__tests__/catalogReducer-test.js
workflow-designer-ui/src/main/frontend/src/features/catalog/__tests__/catalogSagas-test.js
workflow-designer-ui/src/main/frontend/src/features/catalog/catalogActions.js
workflow-designer-ui/src/main/frontend/src/features/catalog/catalogApi.js
workflow-designer-ui/src/main/frontend/src/features/catalog/catalogReducer.js
workflow-designer-ui/src/main/frontend/src/features/catalog/catalogSagas.js
workflow-designer-ui/src/main/frontend/src/features/catalog/views/Header.jsx
workflow-designer-ui/src/main/frontend/src/features/catalog/views/StatusSelector.js [new file with mode: 0644]
workflow-designer-ui/src/main/frontend/src/features/version/composition/Composition.js
workflow-designer-ui/src/main/frontend/src/features/version/general/General.js
workflow-designer-ui/src/main/frontend/src/features/version/general/GeneralView.js
workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/InputOutput.js
workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/InputOutputView.jsx
workflow-designer-ui/src/main/frontend/src/features/version/inputOutput/views/TableBody.jsx
workflow-designer-ui/src/main/frontend/src/features/version/versionController/VersionController.js
workflow-designer-ui/src/main/frontend/src/features/version/versionController/VersionControllerView.jsx
workflow-designer-ui/src/main/frontend/src/features/version/versionController/views/VersionsContainer.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/Overview.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/OverviewView.jsx
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/__tests__/__snapshots__/OverviewView_snapshot-test.js.snap
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/overviewApi.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/overviewConstansts.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/overviewSagas.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/overviewSelectors.js
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowDetails.jsx
workflow-designer-ui/src/main/frontend/src/features/workflow/overview/views/WorkflowHeader.jsx
workflow-designer-ui/src/main/frontend/src/features/workflow/workflowConstants.js
workflow-designer-ui/src/main/frontend/src/features/workflow/workflowReducer.js
workflow-designer-ui/src/main/frontend/src/features/workflow/workflowSelectors.js
workflow-designer-ui/src/main/frontend/src/i18n/languages.json
workflow-designer-ui/src/main/frontend/src/shared/archiveLabel/ArchiveLabel.js [new file with mode: 0644]

index 93c75bf..3baac0b 100644 (file)
@@ -9,3 +9,4 @@
 @import 'components/tree';
 @import 'components/customModal';
 @import 'components/scrollbars';
+@import 'components/archiveLabel';
\ No newline at end of file
diff --git a/workflow-designer-ui/src/main/frontend/resources/scss/components/_archiveLabel.scss b/workflow-designer-ui/src/main/frontend/resources/scss/components/_archiveLabel.scss
new file mode 100644 (file)
index 0000000..a3fa847
--- /dev/null
@@ -0,0 +1,10 @@
+.archive-label {
+    @include body-3;
+    color: $white;
+    background-color: $dark-purple;
+    margin-left: 20px;
+    border-radius: 3px;
+    padding: 1px 10px;
+    align-self: center;
+    text-transform: none;
+}
\ No newline at end of file
index 4fa8d84..7bf784e 100644 (file)
@@ -33,6 +33,8 @@
                }
 
                .version-status-container {
+                       display: flex;
+                       align-items: center;
                        .version-selector-more-versions {
                                @include body-1-emphasis;
                                color: $blue;
index ea5bba2..c5c3203 100644 (file)
@@ -1,18 +1,26 @@
 .wf-catalog {
     overflow: auto;
     background-color: $light-silver;
-    display: grid;
     grid-template-rows: 35px 1fr;
     height: 100vh;
     padding-bottom: 20px;
     .header {
         align-items: center;
         display: flex;
-        justify-content: flex-end;
+        justify-content: space-between;
         background-color: $silver;
         margin-bottom: 2px;
         @include box-shadow(0px 1px 3px 0 rgba(0, 0, 0, 0.2));
-        padding: 8px 60px 0 60px;
+        padding: 8px 60px 0 0px;
+        .wf-status-select {
+            
+            display: grid;
+            width: 200px;
+            height: 34px;
+            margin-top: -8px;            
+            background-color: $light-silver;
+            color: $blue;
+        }
         &__search {
             height: 25px;
         }
index e299fa3..c1c371f 100644 (file)
@@ -64,6 +64,7 @@
     color: $blue;
     justify-content: space-between;
     .title {
+      display: flex;
       @include heading-1;
       text-transform: uppercase;    
     }
           height: 16px;
         }
     }
+    .restore-btn {
+      margin-left: 20px;
+    }
+    .archive-btn {
+      margin-left: 20px;
+      fill: $gray;
+      &:hover {
+        fill: $blue;
+        color: $light-blue;
+        cursor: pointer;
+      }
+    }
   }
 
   @mixin version-page-box-shadow() {
index 867aeeb..3a8fae3 100644 (file)
@@ -32,8 +32,8 @@ const mapStateToProps = state => ({
 });
 
 const mapDispatchToProps = dispatch => ({
-    handleFetchWorkflow: (sort, offset, searchNameFilter) =>
-        dispatch(fetchWorkflow(sort, offset, searchNameFilter)),
+    handleFetchWorkflow: ({ sort, offset, searchNameFilter, status }) =>
+        dispatch(fetchWorkflow({ sort, offset, searchNameFilter, status })),
     clearWorkflow: () => dispatch(clearWorkflowAction),
     showNewWorkflowModal: () =>
         dispatch(
index 3f00252..73ef654 100644 (file)
@@ -40,26 +40,49 @@ class CatalogView extends Component {
 
         const {
             handleFetchWorkflow,
-            catalog: { sort, searchNameFilter }
+            catalog: { sort, status, searchNameFilter }
         } = this.props;
 
         const payload = {
             ...sort
         };
+
         payload[NAME] = payload[NAME] === ASC ? DESC : ASC;
-        handleFetchWorkflow(payload, undefined, searchNameFilter);
+        handleFetchWorkflow({
+            sort: payload,
+            searchNameFilter,
+            status
+        });
     };
+    handleStatusChange = value => {
+        const {
+            handleFetchWorkflow,
+            searchNameFilter,
+            catalog: { sort }
+        } = this.props;
 
+        handleFetchWorkflow({
+            sort,
+            searchNameFilter,
+            status: value
+        });
+    };
     handleScroll = () => {
         const {
             catalog: {
                 paging: { offset },
                 sort,
+                status,
                 searchNameFilter
             },
             handleFetchWorkflow
         } = this.props;
-        handleFetchWorkflow(sort, offset, searchNameFilter);
+        handleFetchWorkflow({
+            sort,
+            offset,
+            searchNameFilter,
+            status
+        });
     };
 
     goToOverviewPage = id => {
@@ -86,6 +109,7 @@ class CatalogView extends Component {
             sort,
             paging: { hasMore, total },
             items,
+            status,
             searchNameFilter
         } = catalog;
         const alphabeticalOrder = sort[NAME];
@@ -93,6 +117,8 @@ class CatalogView extends Component {
         return (
             <div className="wf-catalog">
                 <Header
+                    status={status}
+                    statusChange={this.handleStatusChange}
                     searchChange={this.searchChange}
                     searchValue={searchNameFilter}
                 />
index e37307f..bd2b000 100644 (file)
@@ -23,18 +23,20 @@ import {
     NAME,
     ASC
 } from 'features/catalog/catalogConstants';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 import { fetchWorkflow, updateWorkflow } from 'features/catalog/catalogActions';
 
 describe('Catalog Actions', () => {
     it('should have `fetchWorkflow` action', () => {
         const sort = { [NAME]: ASC };
         const offset = 0;
-
-        expect(fetchWorkflow(sort, offset)).toEqual({
+        const status = WORKFLOW_STATUS.ACTIVE;
+        expect(fetchWorkflow({ sort, offset, status })).toEqual({
             type: FETCH_WORKFLOW,
             payload: {
                 sort,
                 limit: LIMIT,
+                status,
                 offset
             }
         });
index b31aa2e..406e2d5 100644 (file)
@@ -19,6 +19,7 @@
 import { NAME, ASC, DESC } from 'features/catalog/catalogConstants';
 import catalogReducer, { initialState } from 'features/catalog/catalogReducer';
 import { updateWorkflow } from 'features/catalog/catalogActions';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 
 describe('Catalog Reducer', () => {
     const state = {
@@ -29,6 +30,7 @@ describe('Catalog Reducer', () => {
             hasMore: false,
             total: 2
         },
+        status: WORKFLOW_STATUS.ACTIVE,
         sort: {
             [NAME]: ASC
         },
@@ -106,5 +108,4 @@ describe('Catalog Reducer', () => {
             expect.arrayContaining([...dataPayload.items, ...state.items])
         );
     });
-
 });
index 99a5650..d3e9bda 100644 (file)
@@ -25,6 +25,7 @@ import {
     LIMIT,
     SEARCH_CHANGED
 } from 'features/catalog/catalogConstants';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 import catalogApi from '../catalogApi';
 import { fetchWorkflow, updateWorkflow } from 'features/catalog/catalogActions';
 import catalogSaga, {
@@ -51,6 +52,7 @@ describe('Catalog Sagas', () => {
         const sort = {
             [NAME]: DESC
         };
+        const status = WORKFLOW_STATUS.ACTIVE;
         const offset = 0;
         const searchNameFilter = undefined;
         const data = {
@@ -61,6 +63,7 @@ describe('Catalog Sagas', () => {
                 hasMore: false,
                 total: 2
             },
+            status: WORKFLOW_STATUS.ACTIVE,
             searchNameFilter: 'w',
             items: [
                 {
@@ -88,18 +91,19 @@ describe('Catalog Sagas', () => {
                 dispatch: action => dispatched.push(action)
             },
             fetchWorkflowSaga,
-            fetchWorkflow(sort, offset)
+            fetchWorkflow({ sort, offset, status })
         ).done;
 
         expect(dispatched).toEqual(
             expect.arrayContaining([updateWorkflow({ sort, ...data })])
         );
 
-        expect(catalogApi.getWorkflows).toBeCalledWith(
+        expect(catalogApi.getWorkflows).toBeCalledWith({
             sort,
-            LIMIT,
-            offset + LIMIT,
+            status,
+            limit: LIMIT,
+            offset: offset + LIMIT,
             searchNameFilter
-        );
+        });
     });
 });
index f2cb043..81c2284 100644 (file)
@@ -33,11 +33,12 @@ export const {
 
 export const fetchWorkflow = createAction(
     FETCH_WORKFLOW,
-    (sort, offset, searchNameFilter) => ({
+    ({ sort, offset, searchNameFilter, status }) => ({
         sort,
         limit: LIMIT,
         offset,
-        searchNameFilter
+        searchNameFilter,
+        status
     })
 );
 
index f5c9e21..b15f3d8 100644 (file)
@@ -25,11 +25,12 @@ function baseUrl() {
 }
 
 const Api = {
-    getWorkflows: (sort, limit, offset, searchNameFilter) => {
+    getWorkflows: ({ sort, limit, offset, searchNameFilter, status }) => {
         const queryParams = {
             sort: Object.keys(sort).map(key => `${key}:${sort[key]}`),
             limit,
-            offset
+            offset,
+            archiving: status
         };
         if (searchNameFilter) queryParams.searchNameFilter = searchNameFilter;
         const queryString = qs.stringify(queryParams, {
index e5f887b..18507c2 100644 (file)
 * limitations under the License.
 */
 
-import { NAME, ASC, UPDATE_WORKFLOW } from 'features/catalog/catalogConstants';
-import { SEARCH_CHANGED } from './catalogConstants';
-
+import {
+    NAME,
+    ASC,
+    UPDATE_WORKFLOW,
+    SEARCH_CHANGED
+} from 'features/catalog/catalogConstants';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 export const initialState = {
     paging: {
         hasMore: true,
@@ -24,7 +28,8 @@ export const initialState = {
     },
     sort: {
         [NAME]: ASC
-    }
+    },
+    status: WORKFLOW_STATUS.ACTIVE
 };
 
 const catalogReducer = (state = initialState, action) => {
index f177056..dd77bc9 100644 (file)
@@ -28,16 +28,16 @@ import {
 const noOp = () => {};
 
 export function* fetchWorkflowSaga({ payload }) {
-    const { sort, limit, offset, searchNameFilter } = payload;
+    const { sort, limit, offset, searchNameFilter, status } = payload;
     try {
-        const data = yield call(
-            catalogApi.getWorkflows,
+        const data = yield call(catalogApi.getWorkflows, {
             sort,
-            LIMIT,
-            offset === undefined ? 0 : offset + limit,
-            searchNameFilter
-        );
-        yield put(updateWorkflow({ sort, ...data }));
+            limit: LIMIT,
+            offset: offset === undefined ? 0 : offset + limit,
+            searchNameFilter,
+            status
+        });
+        yield put(updateWorkflow({ sort, status, ...data }));
     } catch (e) {
         noOp();
     }
index 864a512..b70c0a5 100644 (file)
 
 import React from 'react';
 import PropTypes from 'prop-types';
-
 import SearchInput from 'shared/searchInput/SearchInput';
+import StatusSelect from './StatusSelector';
 
-const Header = ({ searchChange, searchValue }) => (
+const Header = ({ searchChange, searchValue, statusChange, status }) => (
     <div className="header">
+        <StatusSelect status={status} onChange={statusChange} />
         <div className="header__search">
             <SearchInput
                 dataTestId="wf-catalog-search"
@@ -33,7 +34,9 @@ const Header = ({ searchChange, searchValue }) => (
 
 Header.propTypes = {
     searchChange: PropTypes.func,
-    searchValue: PropTypes.string
+    searchValue: PropTypes.string,
+    statusChange: PropTypes.func,
+    status: PropTypes.string
 };
 
 Header.defaultProps = {
diff --git a/workflow-designer-ui/src/main/frontend/src/features/catalog/views/StatusSelector.js b/workflow-designer-ui/src/main/frontend/src/features/catalog/views/StatusSelector.js
new file mode 100644 (file)
index 0000000..5b77bd5
--- /dev/null
@@ -0,0 +1,24 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
+
+const StatusSelect = ({ status, onChange }) => (
+    <select
+        className="wf-status-select"
+        value={status}
+        data-test-id="status-select"
+        onChange={e => onChange(e.target.value)}>
+        {Object.keys(WORKFLOW_STATUS).map((type, i) => (
+            <option key={`type.${i}`} value={WORKFLOW_STATUS[type]}>
+                {type}
+            </option>
+        ))}
+    </select>
+);
+
+StatusSelect.propTypes = {
+    status: PropTypes.string,
+    onChange: PropTypes.func
+};
+
+export default StatusSelect;
index b91ceda..97697c7 100644 (file)
@@ -24,6 +24,8 @@ import { activitiesSelector } from 'features/activities/activitiesSelectors';
 import { getInputOutputForComposition } from 'features/version/inputOutput/inputOutputSelectors';
 import { getVersionInfo } from 'features/version/general/generalSelectors';
 import { getIsCertified } from 'features/version/general/generalSelectors';
+import { isWorkflowArchive } from 'features/workflow/workflowSelectors';
+
 function mapStateToProps(state) {
     return {
         composition: getComposition(state),
@@ -32,7 +34,7 @@ function mapStateToProps(state) {
         activities: activitiesSelector(state),
         inputOutput: getInputOutputForComposition(state),
         errors: getErrors(state),
-        isReadOnly: getIsCertified(state)
+        isReadOnly: getIsCertified(state) || isWorkflowArchive(state)
     };
 }
 
index f1ba770..ecf8475 100644 (file)
@@ -22,10 +22,10 @@ import {
     getIsCertified
 } from 'features/version/general/generalSelectors';
 import { workflowVersionDetailsChangedAction } from 'features/version/versionConstants';
-
+import { isWorkflowArchive } from 'features/workflow/workflowSelectors';
 const mapStateToProps = state => ({
     versionInfo: getVersionInfo(state),
-    isCertified: getIsCertified(state)
+    isReadOnly: getIsCertified(state) || isWorkflowArchive(state)
 });
 
 const mapDispatchToProps = dispatch => ({
index bd69bfd..e069ffb 100644 (file)
@@ -21,7 +21,7 @@ import { I18n } from 'react-redux-i18n';
 import Description from 'shared/components/Description';
 import { VersionInfo, LabeledValue } from 'shared/components/VersionInfo';
 
-const GeneralView = ({ onDataChange, versionInfo, isCertified }) => {
+const GeneralView = ({ onDataChange, versionInfo, isReadOnly }) => {
     const modifiedValue = I18n.l(versionInfo.modificationTime, {
         dateFormat: 'date.short'
     });
@@ -35,7 +35,7 @@ const GeneralView = ({ onDataChange, versionInfo, isCertified }) => {
                 <Description
                     description={versionInfo.description}
                     onDataChange={onDataChange}
-                    disabled={isCertified}
+                    disabled={isReadOnly}
                 />
                 <VersionInfo>
                     <LabeledValue
@@ -55,7 +55,7 @@ const GeneralView = ({ onDataChange, versionInfo, isCertified }) => {
 GeneralView.propTypes = {
     onDataChange: PropTypes.func,
     versionInfo: PropTypes.object,
-    isCertified: PropTypes.bool
+    isReadOnly: PropTypes.bool
 };
 
 export default GeneralView;
index 94f2f22..c9cd575 100644 (file)
@@ -39,7 +39,7 @@ import {
     changeMandatory,
     remove
 } from 'features/version/inputOutput/inputOutputActions';
-
+import { isWorkflowArchive } from 'features/workflow/workflowSelectors';
 import InputOutputView from 'features/version/inputOutput/InputOutputView';
 
 const mapStateToProps = state => ({
@@ -48,7 +48,7 @@ const mapStateToProps = state => ({
     dataRows: getDataRows(state),
     types: getTypes(state),
     error: getError(state),
-    isCertified: getIsCertified(state)
+    isReadOnly: getIsCertified(state) || isWorkflowArchive(state)
 });
 
 const mapDispatchToProps = dispatch => ({
index 4dea49d..fae8144 100644 (file)
@@ -147,7 +147,7 @@ class InputOutputView extends React.Component {
     };
 
     render() {
-        const { isShowInputs, search, handleAdd, isCertified } = this.props;
+        const { isShowInputs, search, handleAdd, isReadOnly } = this.props;
 
         const addLabel = isShowInputs
             ? I18n.t('workflow.inputOutput.addInput')
@@ -180,7 +180,7 @@ class InputOutputView extends React.Component {
                         </div>
                         <div
                             className={cn('input-output__add', {
-                                disabled: isCertified
+                                disabled: isReadOnly
                             })}
                             data-test-id="wf-input-output-add"
                             onClick={handleAdd}>
@@ -195,7 +195,7 @@ class InputOutputView extends React.Component {
                 </div>
                 <div className="input-output__table">
                     <TableHead />
-                    <TableBody isCertified={isCertified}>
+                    <TableBody isReadOnly={isReadOnly}>
                         <Scrollbars className="scrollbars">
                             {dataRowsView}
                         </Scrollbars>
@@ -218,7 +218,7 @@ InputOutputView.propTypes = {
     ),
     types: PropTypes.array,
     error: PropTypes.object,
-    isCertified: PropTypes.bool,
+    isReadOnly: PropTypes.bool,
     handleChangeError: PropTypes.func,
     handleShowInputs: PropTypes.func,
     handleShowOutputs: PropTypes.func,
index a85bcfb..ed11bbc 100644 (file)
@@ -29,12 +29,12 @@ class TableBody extends React.Component {
     };
 
     render() {
-        const { isCertified, children } = this.props;
+        const { isReadOnly, children } = this.props;
 
         return (
             <div
                 className={cn('input-output__table__tbody', {
-                    disabled: isCertified
+                    disabled: isReadOnly
                 })}>
                 {children}
             </div>
@@ -43,7 +43,7 @@ class TableBody extends React.Component {
 }
 
 TableBody.propTypes = {
-    isCertified: PropTypes.bool,
+    isReadOnly: PropTypes.bool,
     children: PropTypes.node
 };
 
index 5c33433..8f9c9d7 100644 (file)
@@ -21,6 +21,7 @@ import {
     getVersions,
     getSortedVersions
 } from 'features/workflow/overview/overviewSelectors';
+import { isWorkflowArchive } from 'features/workflow/workflowSelectors';
 import {
     getWorkflowId,
     getWorkflowName
@@ -42,6 +43,7 @@ function mapStateToProps(state) {
         savedParams: getSavedObjParams(state),
         hasErrors: getIOErrors(state) || getCompositionHasErrors(state),
         isCertifyDisable: getIsCertified(state),
+        isArchive: isWorkflowArchive(state),
         currentWorkflowVersion: state.currentVersion.general
     };
 }
index 88157e9..cdaf9ae 100644 (file)
@@ -37,7 +37,8 @@ export default class VersionControllerView extends Component {
         certifyVersion: PropTypes.func,
         changeVersion: PropTypes.func,
         isCertifyDisable: PropTypes.bool,
-        hasErrors: PropTypes.bool
+        hasErrors: PropTypes.bool,
+        isArchive: PropTypes.bool
     };
 
     constructor(props) {
@@ -96,8 +97,10 @@ export default class VersionControllerView extends Component {
             workflowName,
             versionsList,
             hasErrors,
-            isCertifyDisable
+            isCertifyDisable,
+            isArchive
         } = this.props;
+        const isReadonly = isCertifyDisable || hasErrors || isArchive;
         return (
             <div className="version-controller-bar">
                 <WorkflowTitle workflowName={workflowName} />
@@ -107,11 +110,12 @@ export default class VersionControllerView extends Component {
                         viewableVersions={versionsList}
                         onOverviewClick={this.routeToOverview}
                         onVersionSelectChange={this.versionChangeCallback}
+                        isArchive={isArchive}
                     />
                     <ActionButtons
-                        saveDisabled={isCertifyDisable || hasErrors}
+                        saveDisabled={isReadonly}
                         onSaveClick={this.sendSaveParamsToServer}
-                        certifyDisabled={isCertifyDisable || hasErrors}
+                        certifyDisabled={isReadonly}
                         onCertifyClick={this.certifyVersion}
                         onUndoClick={this.undoClickCallback}
                     />
index 374e565..c84ab31 100644 (file)
@@ -17,13 +17,15 @@ import React from 'react';
 import VersionSelect from 'features/version/versionController/views/VersionSelect';
 import { I18n } from 'react-redux-i18n';
 import PropTypes from 'prop-types';
+import ArchiveLabel from 'shared/archiveLabel/ArchiveLabel';
 
 const VersionContainer = props => {
-    let {
+    const {
         currentWorkflowVersion,
         viewableVersions,
         onOverviewClick,
-        onVersionSelectChange
+        onVersionSelectChange,
+        isArchive
     } = props;
 
     return (
@@ -41,6 +43,7 @@ const VersionContainer = props => {
                     onClick={onOverviewClick}>
                     {I18n.t('workflow.overview.viewOverview')}
                 </span>
+                {isArchive && <ArchiveLabel />}
             </div>
         </div>
     );
@@ -50,7 +53,8 @@ VersionContainer.propTypes = {
     currentWorkflowVersion: PropTypes.object,
     viewableVersions: PropTypes.arrayOf(Object),
     onOverviewClick: PropTypes.func,
-    onVersionSelectChange: PropTypes.func
+    onVersionSelectChange: PropTypes.func,
+    isArchive: PropTypes.bool
 };
 
 export default VersionContainer;
index 0cce3e5..993879a 100644 (file)
@@ -21,9 +21,12 @@ import {
     getWorkflowData,
     getAllIsVersionsCertifies
 } from 'features/workflow/overview/overviewSelectors';
+import { isWorkflowArchive } from 'features/workflow/workflowSelectors';
 import {
     getVersionsAction,
-    updateWorkflowAction
+    updateWorkflowAction,
+    archiveWorkflowAction,
+    restoreWorkflowAction
 } from 'features/workflow/overview/overviewConstansts';
 import { NEW_VERSION_MODAL } from 'shared/modal/modalWrapperComponents';
 import { showCustomModalAction } from 'shared/modal/modalWrapperActions';
@@ -34,7 +37,8 @@ function mapStateToProps(state) {
         versions: getSortedVersions(state),
         selectedVersion: getSelectedVersionId(state),
         workflow: getWorkflowData(state),
-        isVersionsCertifies: getAllIsVersionsCertifies(state)
+        isVersionsCertifies: getAllIsVersionsCertifies(state),
+        isArchive: isWorkflowArchive(state)
     };
 }
 
@@ -49,7 +53,9 @@ function mapDispatchToProps(dispatch) {
                 })
             ),
         workflowInputChange: payload => dispatch(inputChangeAction(payload)),
-        updateWorkflow: payload => dispatch(updateWorkflowAction(payload))
+        updateWorkflow: payload => dispatch(updateWorkflowAction(payload)),
+        archiveWorkflow: payload => dispatch(archiveWorkflowAction(payload)),
+        restoreWorkflow: payload => dispatch(restoreWorkflowAction(payload))
     };
 }
 
index f87dbfa..0b88a84 100644 (file)
@@ -34,7 +34,10 @@ class OverviewView extends Component {
         location: PropTypes.object,
         match: PropTypes.object,
         updateWorkflow: PropTypes.func,
-        workflowInputChange: PropTypes.func
+        workflowInputChange: PropTypes.func,
+        archiveWorkflow: PropTypes.func,
+        restoreWorkflow: PropTypes.func,
+        isArchive: PropTypes.bool
     };
 
     constructor(props) {
@@ -70,14 +73,23 @@ class OverviewView extends Component {
         const { workflowInputChange } = this.props;
         workflowInputChange({ ...payload });
     };
+    onArchiveWorkflow = () => {
+        const { archiveWorkflow, workflow, history } = this.props;
 
+        archiveWorkflow({ id: workflow.id, history });
+    };
+    onRestoreWorkflow = () => {
+        const { restoreWorkflow, workflow, history } = this.props;
+        restoreWorkflow({ id: workflow.id, history });
+    };
     render() {
         const {
             versions,
             selectedVersion,
             workflow,
             isVersionsCertifies,
-            history
+            history,
+            isArchive
         } = this.props;
         const nodeVersions = versions.map(version => ({
             id: version.id,
@@ -87,9 +99,16 @@ class OverviewView extends Component {
 
         return (
             <div className="overview-page">
-                <WorkflowHeader history={history} name={workflow.name} />
+                <WorkflowHeader
+                    isArchive={isArchive}
+                    archiveWorkflow={this.onArchiveWorkflow}
+                    restoreWorkflow={this.onRestoreWorkflow}
+                    history={history}
+                    name={workflow.name}
+                />
                 <div className="overview-content">
                     <WorkflowDetails
+                        isArchive={isArchive}
                         name={workflow.name}
                         description={workflow.description}
                         modified={workflow.modified}
index 381ec4b..d870bed 100644 (file)
@@ -15,18 +15,33 @@ exports[`OverviewView Snapshot renders correctly 1`] = `
       title
     </div>
     <div
-      className="svg-icon-wrapper  go-catalog-btn  clickable right"
-      disabled={undefined}
-      onClick={[Function]}
+      className="header-buttons"
     >
-      <test-file-stub
-        className="svg-icon __back"
-      />
-      <span
-        className="svg-icon-label "
+      <div
+        className="svg-icon-wrapper  go-catalog-btn  clickable right"
+        disabled={undefined}
+        onClick={[Function]}
+      >
+        <test-file-stub
+          className="svg-icon __back"
+        />
+        <span
+          className="svg-icon-label "
+        >
+          backBtnLabel
+        </span>
+      </div>
+      <div
+        className="svg-icon-wrapper  archive-btn  clickable bottom"
+        disabled={undefined}
+        onClick={[Function]}
+        title="Archive workflow"
       >
-        backBtnLabel
-      </span>
+        <test-file-stub
+          className="svg-icon __archiveBox"
+        />
+        
+      </div>
     </div>
   </div>
   <div
index b7910bc..d48c214 100644 (file)
@@ -35,6 +35,11 @@ const Api = {
             name,
             description
         });
+    },
+    archiveRestoreWorkflow: ({ id, type }) => {
+        return RestfulAPIUtil.post(`${baseUrl()}${id}/archiving`, {
+            status: type
+        });
     }
 };
 
index c90685c..17bd2fd 100644 (file)
 */
 
 import { createAction } from 'redux-actions';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 
 export const FETCH_VERSION_LIST = 'overview/FETCH_VERSION_LIST';
 export const GET_OVERVIEW = 'overview/GET_OVERVIEW';
 export const UPDATE_WORKFLOW = 'overview/UPDATE_WORKFLOW';
+export const ARCHIVE_WORKFLOW = 'overview/ARCHIVE_WORKFLOW';
+export const RESTORE_WORKFLOW = 'overview/RESTORE_WORKFLOW';
 
 export const versionListFetchAction = payload => ({
     type: FETCH_VERSION_LIST,
@@ -34,3 +37,19 @@ export const updateWorkflowAction = createAction(
     UPDATE_WORKFLOW,
     payload => payload
 );
+
+export const archiveWorkflowAction = payload => ({
+    type: ARCHIVE_WORKFLOW,
+    payload: {
+        ...payload,
+        type: WORKFLOW_STATUS.ARCHIVE
+    }
+});
+
+export const restoreWorkflowAction = payload => ({
+    type: RESTORE_WORKFLOW,
+    payload: {
+        ...payload,
+        type: WORKFLOW_STATUS.ACTIVE
+    }
+});
index 6df38a4..f2b4cf1 100644 (file)
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-import { call, takeEvery, put } from 'redux-saga/effects';
+import { call, takeEvery, put, select } from 'redux-saga/effects';
 
 import { genericNetworkErrorAction } from 'wfapp/appConstants';
 import overviewApi from 'features/workflow/overview/overviewApi';
 import {
     versionListFetchAction,
     GET_OVERVIEW,
-    UPDATE_WORKFLOW
+    UPDATE_WORKFLOW,
+    ARCHIVE_WORKFLOW,
+    RESTORE_WORKFLOW
 } from 'features/workflow/overview/overviewConstansts';
 import { setWorkflowAction } from 'features/workflow/workflowConstants';
 import { notificationActions } from 'shared/notifications/notificationsActions';
+import { fetchWorkflow } from 'features/catalog/catalogActions';
+import { WORKFLOW_STATUS } from 'features/workflow/workflowConstants';
 
 export function* getOverview(action) {
     try {
@@ -50,7 +54,31 @@ export function* updateWorkflow(action) {
     }
 }
 
+export function* archiveRestoreWorkflow(action) {
+    try {
+        const { history, ...data } = action.payload;
+        yield call(overviewApi.archiveRestoreWorkflow, data);
+        const {
+            catalog: { sort },
+            searchNameFilter = ''
+        } = yield select();
+
+        yield put(
+            fetchWorkflow({
+                sort,
+                searchNameFilter,
+                status: WORKFLOW_STATUS.ACTIVE
+            })
+        );
+        history.push('/');
+    } catch (e) {
+        yield put(genericNetworkErrorAction(e));
+    }
+}
+
 export function* watchOverview() {
     yield takeEvery(GET_OVERVIEW, getOverview);
     yield takeEvery(UPDATE_WORKFLOW, updateWorkflow);
+    yield takeEvery(ARCHIVE_WORKFLOW, archiveRestoreWorkflow);
+    yield takeEvery(RESTORE_WORKFLOW, archiveRestoreWorkflow);
 }
index cc1f7ff..d6bb191 100644 (file)
@@ -32,7 +32,6 @@ export const getWorkflowModificationTime = state =>
     state && state.workflow.data.modificationTime;
 
 export const getWorkflowId = state => state && state.workflow.data.id;
-
 export const getAllIsVersionsCertifies = createSelector(
     getSortedVersions,
     versions =>
index 5afa8d9..de638a1 100644 (file)
@@ -28,7 +28,12 @@ class WorkflowDetails extends Component {
     };
 
     render() {
-        const { name, description, workflowDetailsChanged } = this.props;
+        const {
+            name,
+            description,
+            workflowDetailsChanged,
+            isArchive
+        } = this.props;
         return (
             <div className="workflow-details">
                 <form onSubmit={this.handleSubmitForm}>
@@ -41,11 +46,12 @@ class WorkflowDetails extends Component {
                         disabled
                     />
                     <Description
+                        disabled={isArchive}
                         description={description}
                         onDataChange={workflowDetailsChanged}
                     />
                     <div className="save-description">
-                        <Button btnType="primary">
+                        <Button disabled={isArchive} btnType="primary">
                             {I18n.t('buttons.saveBtn')}
                         </Button>
                     </div>
@@ -62,7 +68,8 @@ WorkflowDetails.propTypes = {
     description: PropTypes.string,
     defaultDescription: PropTypes.string,
     updateWorkflow: PropTypes.func,
-    workflowDetailsChanged: PropTypes.func
+    workflowDetailsChanged: PropTypes.func,
+    isArchive: PropTypes.bool
 };
 
 export default WorkflowDetails;
index f5bfc3d..3175cbb 100644 (file)
@@ -17,42 +17,91 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { I18n } from 'react-redux-i18n';
 import SVGIcon from 'sdc-ui/lib/react/SVGIcon';
+import Button from 'sdc-ui/lib/react/Button';
+import ArchiveLabel from 'shared/archiveLabel/ArchiveLabel';
 
-const BackBtn = ({ history }) => (
-    <SVGIcon
-        onClick={() => history.push('/')}
-        label={I18n.t('workflow.overview.backBtnLabel')}
-        className="go-catalog-btn"
-        labelPosition="right"
-        name="back"
-    />
+const Buttons = ({ history, archiveWorkflow, restoreWorkflow, isArchive }) => (
+    <div className="header-buttons">
+        <SVGIcon
+            onClick={() => history.push('/')}
+            label={I18n.t('workflow.overview.backBtnLabel')}
+            className="go-catalog-btn"
+            labelPosition="right"
+            name="back"
+        />
+        <ArchiveBtn
+            isArchive={isArchive}
+            restoreWorkflow={restoreWorkflow}
+            archiveWorkflow={archiveWorkflow}
+        />
+    </div>
 );
 
-BackBtn.propTypes = {
-    history: PropTypes.object
+Buttons.propTypes = {
+    history: PropTypes.object,
+    archiveWorkflow: PropTypes.func,
+    isArchive: PropTypes.bool,
+    restoreWorkflow: PropTypes.func
 };
 
-const Title = ({ name }) => (
+const Title = ({ name, isArchive }) => (
     <div className="title">
         {name} - {I18n.t('workflow.overview.title')}
+        {isArchive && <ArchiveLabel />}
     </div>
 );
 Title.propTypes = {
-    name: PropTypes.string
+    name: PropTypes.string,
+    isArchive: PropTypes.bool
+};
+
+const ArchiveBtn = ({ isArchive, archiveWorkflow, restoreWorkflow }) => {
+    return !isArchive ? (
+        <SVGIcon
+            onClick={archiveWorkflow}
+            title="Archive workflow"
+            className="archive-btn"
+            name="archiveBox"
+        />
+    ) : (
+        <Button className="restore-btn" onClick={restoreWorkflow}>
+            RESTORE
+        </Button>
+    );
+};
+ArchiveBtn.propTypes = {
+    status: PropTypes.string,
+    archiveWorkflow: PropTypes.func,
+    restoreWorkflow: PropTypes.func,
+    isArchive: PropTypes.bool
 };
 
-const WorkflowHeader = ({ name, history }) => {
+const WorkflowHeader = ({
+    name,
+    history,
+    archiveWorkflow,
+    restoreWorkflow,
+    isArchive
+}) => {
     return (
         <div className="overview-header">
-            <Title name={name} />
-            <BackBtn history={history} />
+            <Title isArchive={isArchive} name={name} />
+            <Buttons
+                restoreWorkflow={restoreWorkflow}
+                archiveWorkflow={archiveWorkflow}
+                isArchive={isArchive}
+                history={history}
+            />
         </div>
     );
 };
 
 WorkflowHeader.propTypes = {
     name: PropTypes.string,
-    history: PropTypes.object
+    history: PropTypes.object,
+    archiveWorkflow: PropTypes.func,
+    restoreWorkflow: PropTypes.func,
+    isArchive: PropTypes.bool
 };
 
 export default WorkflowHeader;
index cedcafe..a9f4aa5 100644 (file)
 */
 import { createAction } from 'redux-actions';
 
+export const WORKFLOW_STATUS = {
+    ACTIVE: 'ACTIVE',
+    ARCHIVE: 'ARCHIVED'
+};
+
 export const CLEAR_WORKFLOW_DATA = 'workflow/CLEAR_WORKFLOW_DATA';
 export const SET_WORKFLOW = 'workflow/SET_WORKFLOW';
 
index c0b0557..70d6e5b 100644 (file)
@@ -37,6 +37,11 @@ function workflowReducer(state = {}, action) {
             return {
                 ...action.payload
             };
+        //TODO change it when BE is done
+        // return {
+        //     ...action.payload,
+        //     status: 'archive'
+        // };
         case VALIDATION_ERROR:
             return {
                 ...state,
index bef67c2..e03bfbf 100644 (file)
@@ -13,7 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-
+import { WORKFLOW_STATUS } from './workflowConstants';
 export const getWorkflowName = state =>
     state && state.workflow.data.name && state.workflow.data.name;
 export const getTrimWorkflowName = state =>
@@ -21,3 +21,14 @@ export const getTrimWorkflowName = state =>
 export const getWorkflowId = state => state && state.workflow.data.id;
 export const getWorkflowDescription = state =>
     state && state.workflow.data.description;
+export const getWorkflowStatus = state =>
+    state &&
+    state.workflow &&
+    state.workflow.data &&
+    state.workflow.data.status;
+export const isWorkflowArchive = state =>
+    state &&
+    state.workflow &&
+    state.workflow.data &&
+    state.workflow.data.status &&
+    state.workflow.data.status === WORKFLOW_STATUS.ARCHIVE;
index 42f2475..6b83937 100644 (file)
@@ -46,7 +46,8 @@
                 "newVersion": "Create New Version",
                 "title": "Overview",
                 "lastEdited": "Last Edited On",
-                "backBtnLabel": "WORKFLOW CATALOG"
+                "backBtnLabel": "WORKFLOW CATALOG",
+                "archived": "Archived"
             },
             "inputOutput": {
                 "name": "Name",
diff --git a/workflow-designer-ui/src/main/frontend/src/shared/archiveLabel/ArchiveLabel.js b/workflow-designer-ui/src/main/frontend/src/shared/archiveLabel/ArchiveLabel.js
new file mode 100644 (file)
index 0000000..45b3909
--- /dev/null
@@ -0,0 +1,8 @@
+import React from 'react';
+import { I18n } from 'react-redux-i18n';
+
+const ArchiveLabel = () => (
+    <div className="archive-label">{I18n.t('workflow.overview.archived')}</div>
+);
+
+export default ArchiveLabel;