Skip to content

Commit

Permalink
feat: added clone workflow definition button (#2594)
Browse files Browse the repository at this point in the history
* feat: added clone workflow definition button

* feat: added clone button to workflows table
  • Loading branch information
chesterkmr authored Jul 31, 2024
1 parent 504e1b6 commit 97bc6fa
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 1 deletion.
2 changes: 2 additions & 0 deletions apps/workflows-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
},
"dependencies": {
"@ballerine/common": "^0.9.16",
"@ballerine/ui": "^0.5.11",
"@lukemorales/query-key-factory": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-dialog": "1.0.4",
Expand All @@ -26,6 +27,7 @@
"@radix-ui/react-separator": "^1.0.2",
"@radix-ui/react-slot": "^1.0.1",
"@radix-ui/react-tabs": "^1.0.4",
"@rjsf/utils": "^5.9.0",
"@tanstack/react-query": "^4.28.0",
"@tanstack/react-table": "^8.9.2",
"@xstate/inspect": "^0.7.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Button } from '@/components/atoms/Button';
import { Dialog, DialogContent, DialogTrigger } from '@/components/atoms/Dialog';
import {
formSchema,
uiSchema,
} from '@/components/molecules/CloneWorkflowDefinitionButton/form-schema';
import { useCloneWorkflowDefinitionMutation } from '@/pages/WorkflowDefinitions/hooks/useCloneWorkflowDefinitionMutation';
import { DynamicForm } from '@ballerine/ui';
import { FunctionComponent, useCallback, useEffect, useState } from 'react';

interface ICloneWorkflowDefinitionButtonProps {
workflowDefinitionId: string;
}

export const CloneWorkflowDefinitionButton: FunctionComponent<
ICloneWorkflowDefinitionButtonProps
> = ({ workflowDefinitionId }) => {
const [isDialogOpen, setIsDialogOpen] = useState(false);
const { mutate, isLoading, isSuccess } = useCloneWorkflowDefinitionMutation();

const handleSubmit = useCallback(
async (formData: Record<string, any>) => {
const values: { name: string; displayName: string } = formData as any;

mutate({ workflowDefinitionId, ...values });
},
[workflowDefinitionId, mutate],
);

useEffect(() => {
if (isSuccess) {
setIsDialogOpen(false);
}
}, [isSuccess]);

return (
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogTrigger asChild>
<Button>Clone</Button>
</DialogTrigger>
<DialogContent>
<DynamicForm
schema={formSchema}
uiSchema={uiSchema}
disabled={isLoading}
onSubmit={handleSubmit}
/>
</DialogContent>
</Dialog>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { RJSFSchema, UiSchema } from '@rjsf/utils';

export const formSchema: RJSFSchema = {
type: 'object',
required: ['name', 'displayName'],
properties: {
name: {
type: 'string',
},
displayName: {
type: 'string',
},
},
};

export const uiSchema: UiSchema = {
name: {
'ui:placeholder': 'ballerine',
'ui:label': 'Name',
},
displayName: {
'ui:placeholder': 'Ballerine',
'ui:label': 'Display Name',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './CloneWorkflowDefinitionButton';
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HealthIndicator } from '@/components/atoms/HealthIndicator';
import { CloneWorkflowDefinitionButton } from '@/components/molecules/CloneWorkflowDefinitionButton';
import { JSONViewButton } from '@/components/molecules/JSONViewButton';
import { DataTableColumnHeader } from '@/components/molecules/WorkflowsTable/components/DataTableColumnHeader';
import { StateUpdaterColumn } from '@/components/molecules/WorkflowsTable/components/StateUpdaterColumn';
Expand All @@ -20,6 +21,11 @@ export const defaultColumns: WorkflowTableColumnDef<IWorkflow>[] = [
<DataTableColumnHeader column={column} title="Workflow Definition Name" />
),
},
{
accessorKey: 'workflowDefinitionId',
cell: info => <CloneWorkflowDefinitionButton workflowDefinitionId={info.getValue<string>()} />,
header: '',
},
{
accessorKey: 'status',
cell: info => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export type WorkflowTableColumnKeys =
| 'view-workflow'
| 'resolvedAt'
| 'createdBy'
| 'createdAt';
| 'createdAt'
| 'workflowDefinitionId';

export type WorkflowTableColumnDef<TData> = Omit<ColumnDef<TData>, 'accessorKey'> & {
accessorFn?: AccessorFnColumnDef<TData>['accessorFn'];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
CloneWorkflowDefinitionByIdDto,
GetUIDefinitionQuery,
GetWorkflowDefinitionDto,
GetWorkflowDefinitionsListDto,
Expand Down Expand Up @@ -68,3 +69,12 @@ export const upgradeWorkflowDefinitionVersionById = async (

return result.data;
};

export const cloneWorkflowDefinitionById = async (dto: CloneWorkflowDefinitionByIdDto) => {
const result = await request.post(`/workflow-definition/${dto.workflowDefinitionId}/copy`, {
name: dto.name,
displayName: dto.displayName,
});

return result.data;
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,9 @@ export interface UpdateWorkflowDefinitionExtensionsByIdDto {
export interface UpgradeWorkflowDefinitionVersionByIdDto {
workflowDefinitionId: string;
}

export interface CloneWorkflowDefinitionByIdDto {
workflowDefinitionId: string;
name: string;
displayName: string;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CloneWorkflowDefinitionButton } from '@/components/molecules/CloneWorkflowDefinitionButton';
import { JSONViewButton } from '@/components/molecules/JSONViewButton';
import { IWorkflowDefinition } from '@/domains/workflow-definitions';
import { valueOrNA } from '@/utils/value-or-na';
Expand Down Expand Up @@ -74,6 +75,10 @@ export const workflowDefinitionsTableColumns = [
cell: info => info.getValue<number>(),
header: () => 'Version',
}),
columnHelper.accessor('id', {
cell: info => <CloneWorkflowDefinitionButton workflowDefinitionId={info.getValue()} />,
header: () => '',
}),
columnHelper.accessor('id', {
cell: info => (
<Link to={`/workflow-definitions/${info.row.original.id}`}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useCloneWorkflowDefinitionMutation';
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
cloneWorkflowDefinitionById,
CloneWorkflowDefinitionByIdDto,
} from '@/domains/workflow-definitions';
import { queryClient } from '@/lib/react-query/query-client';
import { useMutation } from '@tanstack/react-query';
import { toast } from 'sonner';

export const useCloneWorkflowDefinitionMutation = () => {
return useMutation({
mutationFn: async (dto: CloneWorkflowDefinitionByIdDto) => cloneWorkflowDefinitionById(dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['workflowDefinitions'] });

toast.success('Workflow Definition cloned succesfully.');
},
onError: () => {
toast.error('Failed to clone Workflow Definition.');
},
});
};
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit 97bc6fa

Please sign in to comment.