diff --git a/frontend/packages/volto-workflow-manager/src/components/States/State.tsx b/frontend/packages/volto-workflow-manager/src/components/States/State.tsx index 846af94..3dc5bb7 100644 --- a/frontend/packages/volto-workflow-manager/src/components/States/State.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/States/State.tsx @@ -12,7 +12,7 @@ import { Item, ProgressCircle, } from '@adobe/react-spectrum'; -import { listStates } from '../../actions/state'; +import { listStates, deleteState } from '../../actions/state'; import { listTransitions } from '../../actions/transition'; import PropertiesTab from './Tabs/PropertiesTab'; import TransitionsTab from './Tabs/TransitionsTab'; @@ -137,6 +137,17 @@ const State: React.FC = ({ }); }, []); + const handleDeleteState = useCallback( + (stateId: string) => { + dispatch(deleteState(workflowId, stateId)); + setSelectedStateId(null); + setLocalStateData(null); + setInitialStateData(null); + onDataChange(null); + }, + [dispatch, workflowId, onDataChange], + ); + if (isLoadingData && !statesInfo.loaded) { return ; } @@ -175,6 +186,8 @@ const State: React.FC = ({ handleStateChange({ properties })} isDisabled={areTabsDisabled} diff --git a/frontend/packages/volto-workflow-manager/src/components/States/Tabs/PropertiesTab.tsx b/frontend/packages/volto-workflow-manager/src/components/States/Tabs/PropertiesTab.tsx index 58f60b0..99c4715 100644 --- a/frontend/packages/volto-workflow-manager/src/components/States/Tabs/PropertiesTab.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/States/Tabs/PropertiesTab.tsx @@ -1,12 +1,24 @@ import React, { useCallback } from 'react'; -import { View, Text } from '@adobe/react-spectrum'; -import Form from '@plone/volto/components/manage/Form/Form'; +import { + View, + Text, + Flex, + DialogTrigger, + AlertDialog, + Button, +} from '@adobe/react-spectrum'; +import { BlockDataForm } from '@plone/volto/components/manage/Form'; +import Icon from '@plone/volto/components/theme/Icon/Icon'; +import deleteIcon from '@plone/volto/icons/delete.svg'; + import type { PropertiesTabProps } from '../../../types/state'; const PropertiesTab: React.FC = ({ data, schema, onChange, + handleDeleteState, + selectedStateId, isDisabled, }) => { const handleChangeField = useCallback( @@ -25,12 +37,27 @@ const PropertiesTab: React.FC = ({ return ( -
+ + + handleDeleteState(selectedStateId)} + > + Are you sure you want to delete '{data.title}' state? This action + cannot be undone. + + + + ); diff --git a/frontend/packages/volto-workflow-manager/src/components/Transitions/Tabs/PropertiesTab.tsx b/frontend/packages/volto-workflow-manager/src/components/Transitions/Tabs/PropertiesTab.tsx index 96d1944..4273c4d 100644 --- a/frontend/packages/volto-workflow-manager/src/components/Transitions/Tabs/PropertiesTab.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/Transitions/Tabs/PropertiesTab.tsx @@ -1,13 +1,26 @@ import React, { useCallback } from 'react'; -import { View, Text } from '@adobe/react-spectrum'; -import Form from '@plone/volto/components/manage/Form/Form'; + import type { PropertiesTabProps } from '../../../types/transition'; +import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm'; +import { + View, + Text, + Flex, + DialogTrigger, + AlertDialog, + Button, +} from '@adobe/react-spectrum'; + +import Icon from '@plone/volto/components/theme/Icon/Icon'; +import deleteIcon from '@plone/volto/icons/delete.svg'; const PropertiesTab: React.FC = ({ data, schema, onChange, isDisabled, + handleDeleteTransition, + selectedTransitionId, }) => { const handleChangeField = useCallback( (id: string, value: any) => { @@ -25,13 +38,27 @@ const PropertiesTab: React.FC = ({ return ( - + + + handleDeleteTransition(selectedTransitionId)} + > + Are you sure you want to delete '{data.title}' transition? This + action cannot be undone. + + + + ); diff --git a/frontend/packages/volto-workflow-manager/src/components/Transitions/Transition.tsx b/frontend/packages/volto-workflow-manager/src/components/Transitions/Transition.tsx index f3da088..2cb3790 100644 --- a/frontend/packages/volto-workflow-manager/src/components/Transitions/Transition.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/Transitions/Transition.tsx @@ -12,7 +12,7 @@ import { Heading, ProgressCircle, } from '@adobe/react-spectrum'; -import { listTransitions } from '../../actions/transition'; +import { listTransitions, deleteTransition } from '../../actions/transition'; import { listStates } from '../../actions/state'; import PropertiesTab from './Tabs/PropertiesTab'; import GuardsTab from './Tabs/GuardsTab'; @@ -144,6 +144,17 @@ const Transition: React.FC = ({ setSelectedTransitionId(key as string); }; + const handleDeleteTransition = useCallback( + (transitionId: string) => { + dispatch(deleteTransition(workflowId, transitionId)); + setSelectedTransitionId(null); + setLocalTransitionData(null); + setInitialTransitionData(null); + onDataChange(null); + }, + [dispatch, workflowId, onDataChange], + ); + const propertiesSchema = useMemo( () => ({ title: 'Transition Properties', @@ -215,6 +226,8 @@ const Transition: React.FC = ({ key={`properties-${selectedTransitionId}`} data={localTransitionData?.properties} schema={propertiesSchema} + handleDeleteTransition={handleDeleteTransition} + selectedTransitionId={selectedTransitionId} onChange={(properties) => handleTransitionChange({ properties }) } diff --git a/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowTab.tsx b/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowTab.tsx index 37a59c0..46b35aa 100644 --- a/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowTab.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowTab.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect, useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { View, ProgressCircle } from '@adobe/react-spectrum'; -import Form from '@plone/volto/components/manage/Form/Form'; +import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm'; import { getWorkflow } from '../../actions/workflow'; import type { GlobalRootState } from '../../types'; import type { WorkflowTabProps } from '../../types/workflow'; @@ -84,13 +84,11 @@ const WorkflowTab: React.FC = ({ return ( - ); diff --git a/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowView.tsx b/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowView.tsx index fafb4ee..2e80c9c 100644 --- a/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowView.tsx +++ b/frontend/packages/volto-workflow-manager/src/components/Workflow/WorkflowView.tsx @@ -57,10 +57,21 @@ const WorkflowView: React.FC = ({ const isSavingWorkflow = useAppSelector( (state) => state.workflow.operation.loading, ); + const isDeletingState = useAppSelector( + (state) => state.state.delete?.loading || false, + ); + const isDeletingTransition = useAppSelector( + (state) => state.transition.delete?.loading || false, + ); const isSaving = isSavingState || isSavingTransition || isSavingWorkflow; + const isDeleting = isDeletingState || isDeletingTransition; const prevIsSaving = useRef(isSaving); + const prevIsDeleting = useRef(isDeleting); + const prevIsDeletingState = useRef(isDeletingState); + const prevIsDeletingTransition = useRef(isDeletingTransition); + useEffect(() => { if (prevIsSaving.current && !isSaving) { toast.success(); @@ -69,6 +80,30 @@ const WorkflowView: React.FC = ({ prevIsSaving.current = isSaving; }, [isSaving, dispatch, workflowId]); + useEffect(() => { + if (prevIsDeleting.current && !isDeleting) { + const stateDeleteSuccess = + !isDeletingState && prevIsDeletingState.current; + const transitionDeleteSuccess = + !isDeletingTransition && prevIsDeletingTransition.current; + + if (stateDeleteSuccess) { + toast.success( + , + ); + } else if (transitionDeleteSuccess) { + toast.success( + , + ); + } + + dispatch(getWorkflow(workflowId)); + } + prevIsDeleting.current = isDeleting; + prevIsDeletingState.current = isDeletingState; + prevIsDeletingTransition.current = isDeletingTransition; + }, [isDeleting, isDeletingState, isDeletingTransition, dispatch, workflowId]); + const handleDataChange = useCallback( (payload: any | null, kind: 'workflow' | 'state' | 'transition') => { if (payload) { @@ -171,7 +206,7 @@ const WorkflowView: React.FC = ({ diff --git a/frontend/packages/volto-workflow-manager/src/index.js b/frontend/packages/volto-workflow-manager/src/index.js index 27f41f0..8f851bd 100644 --- a/frontend/packages/volto-workflow-manager/src/index.js +++ b/frontend/packages/volto-workflow-manager/src/index.js @@ -1,6 +1,7 @@ import WorkflowControlPanel from './components/Controlpanel/WorkflowPanel'; import { workflow, state, transition } from './reducers'; import './theme/main.scss'; + const applyConfig = (config) => { config.settings.isMultilingual = false; config.settings.supportedLanguages = ['en']; @@ -28,10 +29,7 @@ const applyConfig = (config) => { state, transition, }; - config.views = { - ...config.views, - contentTypesViews: {}, - }; + return config; }; diff --git a/frontend/packages/volto-workflow-manager/src/types/state.ts b/frontend/packages/volto-workflow-manager/src/types/state.ts index 8a17256..313d4b8 100644 --- a/frontend/packages/volto-workflow-manager/src/types/state.ts +++ b/frontend/packages/volto-workflow-manager/src/types/state.ts @@ -46,6 +46,8 @@ export interface PropertiesTabProps { schema: any; onChange: (newData: PropertiesData) => void; isDisabled: boolean; + handleDeleteState: (stateId: string) => void; + selectedStateId: string | null; } export interface TransitionsData { diff --git a/frontend/packages/volto-workflow-manager/src/types/transition.ts b/frontend/packages/volto-workflow-manager/src/types/transition.ts index 16f5524..b864f20 100644 --- a/frontend/packages/volto-workflow-manager/src/types/transition.ts +++ b/frontend/packages/volto-workflow-manager/src/types/transition.ts @@ -37,6 +37,8 @@ export interface PropertiesTabProps { schema: any; onChange: (newData: PropertiesData) => void; isDisabled: boolean; + handleDeleteTransition: (transitionId: string | null) => void; + selectedTransitionId: string | null; } export interface SourceStatesData {