diff --git a/apps/backoffice-v2/CHANGELOG.md b/apps/backoffice-v2/CHANGELOG.md index 4b29a244c8..d8ffb11998 100644 --- a/apps/backoffice-v2/CHANGELOG.md +++ b/apps/backoffice-v2/CHANGELOG.md @@ -1,5 +1,25 @@ # @ballerine/backoffice-v2 +## 0.7.81 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/blocks@0.2.29 + - @ballerine/common@0.9.58 + - @ballerine/react-pdf-toolkit@1.2.50 + - @ballerine/ui@0.5.50 + - @ballerine/workflow-browser-sdk@0.6.77 + - @ballerine/workflow-node-sdk@0.6.77 + +## 0.7.80 + +### Patch Changes + +- @ballerine/workflow-browser-sdk@0.6.76 +- @ballerine/workflow-node-sdk@0.6.76 + ## 0.7.79 ### Patch Changes diff --git a/apps/backoffice-v2/package.json b/apps/backoffice-v2/package.json index 39e5d28999..5af55b3059 100644 --- a/apps/backoffice-v2/package.json +++ b/apps/backoffice-v2/package.json @@ -1,6 +1,6 @@ { "name": "@ballerine/backoffice-v2", - "version": "0.7.79", + "version": "0.7.81", "description": "Ballerine - Backoffice", "homepage": "https://github.com/ballerine-io/ballerine", "type": "module", @@ -51,12 +51,12 @@ "preview": "vite preview" }, "dependencies": { - "@ballerine/blocks": "0.2.28", - "@ballerine/common": "0.9.57", - "@ballerine/react-pdf-toolkit": "^1.2.48", - "@ballerine/ui": "^0.5.48", - "@ballerine/workflow-browser-sdk": "0.6.75", - "@ballerine/workflow-node-sdk": "0.6.75", + "@ballerine/blocks": "0.2.29", + "@ballerine/common": "0.9.58", + "@ballerine/react-pdf-toolkit": "^1.2.50", + "@ballerine/ui": "^0.5.50", + "@ballerine/workflow-browser-sdk": "0.6.77", + "@ballerine/workflow-node-sdk": "0.6.77", "@botpress/webchat": "^2.1.10", "@botpress/webchat-generator": "^0.2.9", "@fontsource/inter": "^4.5.15", @@ -148,8 +148,8 @@ "zod": "^3.22.3" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config-react": "^2.0.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config-react": "^2.0.27", "@cspell/cspell-types": "^6.31.1", "@faker-js/faker": "^7.6.0", "@playwright/test": "^1.32.1", diff --git a/apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx b/apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx index 4117504dd1..f64fa05ccd 100644 --- a/apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx +++ b/apps/backoffice-v2/src/lib/blocks/hooks/useDocumentBlocks/useDocumentBlocks.tsx @@ -440,14 +440,12 @@ export const useDocumentBlocks = ({ const fieldValue = getFieldValue(); const isEditableDecision = isDoneWithRevision || !decision?.status; const isIndividual = checkIsIndividual(workflow); - const isEditableType = (title === 'type' && isIndividual) || title !== 'type'; const isEditableCategory = (title === 'category' && isIndividual) || title !== 'category'; const isEditableField = [ isEditableDecision, isEditable, caseState.writeEnabled, - isEditableType, isEditableCategory, ].every(Boolean); diff --git a/apps/kyb-app/CHANGELOG.md b/apps/kyb-app/CHANGELOG.md index bd419fe2d1..84b3716849 100644 --- a/apps/kyb-app/CHANGELOG.md +++ b/apps/kyb-app/CHANGELOG.md @@ -1,5 +1,22 @@ # kyb-app +## 0.3.93 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/blocks@0.2.29 + - @ballerine/common@0.9.58 + - @ballerine/ui@0.5.50 + - @ballerine/workflow-browser-sdk@0.6.77 + +## 0.3.92 + +### Patch Changes + +- @ballerine/workflow-browser-sdk@0.6.76 + ## 0.3.91 ### Patch Changes diff --git a/apps/kyb-app/package.json b/apps/kyb-app/package.json index 15a3923dc6..1ad628ec17 100644 --- a/apps/kyb-app/package.json +++ b/apps/kyb-app/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/kyb-app", "private": true, - "version": "0.3.91", + "version": "0.3.93", "type": "module", "scripts": { "dev": "vite", @@ -15,10 +15,10 @@ "test:dev": "vitest" }, "dependencies": { - "@ballerine/blocks": "0.2.28", - "@ballerine/common": "^0.9.57", - "@ballerine/ui": "0.5.49", - "@ballerine/workflow-browser-sdk": "0.6.75", + "@ballerine/blocks": "0.2.29", + "@ballerine/common": "^0.9.58", + "@ballerine/ui": "0.5.50", + "@ballerine/workflow-browser-sdk": "0.6.77", "@lukemorales/query-key-factory": "^1.0.3", "@radix-ui/react-icons": "^1.3.0", "@rjsf/core": "^5.9.0", @@ -64,8 +64,8 @@ "zod": "^3.23.4" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config-react": "^2.0.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config-react": "^2.0.27", "@jest/globals": "^29.7.0", "@sentry/vite-plugin": "^2.9.0", "@testing-library/jest-dom": "^6.1.4", diff --git a/apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx b/apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx index 37bd012c26..b4c79d42dd 100644 --- a/apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx +++ b/apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx @@ -246,19 +246,43 @@ export const CollectionFlow = withSessionProtected(() => { {localStorage.getItem('devmode') ? ( -
- DEBUG -
- {currentPage - ? currentPage.stateName - : 'Page not found and state ' + state} +
+
+
+ + Debug Mode Active +
-
- -
diff --git a/apps/workflows-dashboard/CHANGELOG.md b/apps/workflows-dashboard/CHANGELOG.md index d58f067941..b241ebdf69 100644 --- a/apps/workflows-dashboard/CHANGELOG.md +++ b/apps/workflows-dashboard/CHANGELOG.md @@ -1,5 +1,14 @@ # @ballerine/workflows-dashboard +## 0.2.27 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + - @ballerine/ui@0.5.50 + ## 0.2.26 ### Patch Changes diff --git a/apps/workflows-dashboard/package.json b/apps/workflows-dashboard/package.json index 17901d6496..29e8cd441a 100644 --- a/apps/workflows-dashboard/package.json +++ b/apps/workflows-dashboard/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflows-dashboard", "private": false, - "version": "0.2.26", + "version": "0.2.27", "type": "module", "scripts": { "spellcheck": "cspell \"*\"", @@ -15,8 +15,8 @@ "test": "NODE_ENV=test jest" }, "dependencies": { - "@ballerine/common": "^0.9.55", - "@ballerine/ui": "^0.5.48", + "@ballerine/common": "^0.9.58", + "@ballerine/ui": "^0.5.50", "@lukemorales/query-key-factory": "^1.0.3", "@radix-ui/react-avatar": "^1.0.3", "@radix-ui/react-dialog": "1.0.4", @@ -63,8 +63,8 @@ "zod": "^3.22.3" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config-react": "^2.0.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config-react": "^2.0.27", "@cspell/cspell-types": "^6.31.1", "@types/axios": "^0.14.0", "@types/classnames": "^2.3.1", diff --git a/apps/workflows-dashboard/src/components/molecules/WorkflowsTable/columns.tsx b/apps/workflows-dashboard/src/components/molecules/WorkflowsTable/columns.tsx index 0150446af9..f171874ff6 100644 --- a/apps/workflows-dashboard/src/components/molecules/WorkflowsTable/columns.tsx +++ b/apps/workflows-dashboard/src/components/molecules/WorkflowsTable/columns.tsx @@ -7,16 +7,49 @@ import { WorkflowTableColumnDef } from '@/components/molecules/WorkflowsTable/ty import { IWorkflow } from '@/domains/workflows/api/workflow'; import { formatDate } from '@/utils/format-date'; import { getWorkflowHealthStatus } from '@/utils/get-workflow-health-status'; +import { Eye } from 'lucide-react'; +import { toast } from 'sonner'; -export const defaultColumns: WorkflowTableColumnDef[] = [ +export const defaultColumns: Array> = [ { accessorKey: 'id', - cell: info => info.getValue(), - header: () => 'ID', + cell: info => ( +
+ {info.getValue()} + +
+ ), + header: () => ID, }, { accessorKey: 'workflowDefinitionName', - cell: info => info.getValue(), + cell: info => {info.getValue()}, header: ({ column }) => ( ), @@ -24,14 +57,14 @@ export const defaultColumns: WorkflowTableColumnDef[] = [ { accessorKey: 'workflowDefinitionId', cell: info => ()} />, - header: '', + header: () => '', }, { accessorKey: 'status', cell: info => ( -
+
- {info.getValue() || ''} + {info.getValue() || ''}
), header: ({ column }) => , @@ -50,34 +83,47 @@ export const defaultColumns: WorkflowTableColumnDef[] = [ { accessorKey: 'assignee', accessorFn: row => (row.assignee ? `${row.assignee.firstName} ${row.assignee.lastName}` : '-'), - cell: info => info.getValue(), + cell: info => {info.getValue()}, header: ({ column }) => , }, { accessorKey: 'context', accessorFn: row => JSON.stringify(row.context), - cell: info => ()} />, - header: () => 'Context', + cell: info => ( +
+ + } + json={info.getValue()} + /> +
+ ), + header: () => Context, }, { accessorKey: 'view-workflow', accessorFn: row => row.id, cell: () => '-', - header: () => 'Workflow', + header: () => Workflow, }, { accessorKey: 'resolvedAt', - cell: info => (info.getValue() ? formatDate(info.getValue()) : '-'), + cell: info => ( + + {info.getValue() ? formatDate(info.getValue()) : '-'} + + ), header: ({ column }) => , }, { accessorKey: 'createdBy', - cell: info => info.getValue(), + cell: info => {info.getValue()}, header: ({ column }) => , }, { accessorKey: 'createdAt', - cell: info => formatDate(info.getValue()), + cell: info => {formatDate(info.getValue())}, header: ({ column }) => , }, ]; diff --git a/apps/workflows-dashboard/src/domains/filters/filters.api.ts b/apps/workflows-dashboard/src/domains/filters/filters.api.ts index a31129269f..007df59010 100644 --- a/apps/workflows-dashboard/src/domains/filters/filters.api.ts +++ b/apps/workflows-dashboard/src/domains/filters/filters.api.ts @@ -1,4 +1,8 @@ -import { GetFiltersListDto, GetFiltersResponse } from '@/domains/filters/filters.types'; +import { + CreateFilterDto, + GetFiltersListDto, + GetFiltersResponse, +} from '@/domains/filters/filters.types'; import { request } from '@/lib/request'; export const fetchFiltersList = async (query: GetFiltersListDto) => { @@ -8,3 +12,9 @@ export const fetchFiltersList = async (query: GetFiltersListDto) => { return result.data; }; + +export const createFilter = async (dto: CreateFilterDto) => { + const result = await request.post('/external/filters', dto); + + return result.data; +}; diff --git a/apps/workflows-dashboard/src/domains/filters/filters.types.ts b/apps/workflows-dashboard/src/domains/filters/filters.types.ts index d88c05e5e1..47e053780e 100644 --- a/apps/workflows-dashboard/src/domains/filters/filters.types.ts +++ b/apps/workflows-dashboard/src/domains/filters/filters.types.ts @@ -4,6 +4,7 @@ export interface IFilter { entity: string; query: object; createdAt: string; + projectId: string; } export interface GetFiltersListDto { @@ -18,3 +19,19 @@ export interface GetFiltersResponse { pages: number; }; } +export interface CreateFilterDto { + name: string; + entity: string; + query: { + where: { + businessId: { + not: null; + }; + workflowDefinitionId: { + in: string[]; + }; + }; + select: object; + }; + projectId: string; +} diff --git a/apps/workflows-dashboard/src/domains/filters/query-keys.ts b/apps/workflows-dashboard/src/domains/filters/query-keys.ts index dc34a06fdc..0fd91d50cd 100644 --- a/apps/workflows-dashboard/src/domains/filters/query-keys.ts +++ b/apps/workflows-dashboard/src/domains/filters/query-keys.ts @@ -1,5 +1,5 @@ -import { fetchFiltersList } from '@/domains/filters/filters.api'; -import { GetFiltersListDto } from '@/domains/filters/filters.types'; +import { createFilter, fetchFiltersList } from '@/domains/filters/filters.api'; +import { CreateFilterDto, GetFiltersListDto } from '@/domains/filters/filters.types'; import { createQueryKeys } from '@lukemorales/query-key-factory'; export const filtersQueryKeys = createQueryKeys('filters', { @@ -7,4 +7,8 @@ export const filtersQueryKeys = createQueryKeys('filters', { queryKey: [{ query }], queryFn: () => fetchFiltersList(query), }), + create: () => ({ + queryKey: ['create'], + queryFn: (dto: CreateFilterDto) => createFilter(dto), + }), }); diff --git a/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.api.ts b/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.api.ts index 4da9402985..367ee6a706 100644 --- a/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.api.ts +++ b/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.api.ts @@ -21,7 +21,11 @@ export const updateUIDefinition = async (dto: UpdateUIDefinitionDto) => { }; export const copyUIDefinition = async (dto: CopyUIDefinitionDto) => { - const result = await request.post(`/ui-definition/${dto.uiDefinitionId}/copy`); + const result = await request.post(`/ui-definition/${dto.uiDefinitionId}/copy`, { + name: dto.name, + }); + + return result.data; }; export const fetchUIDefinition = async (dto: GetUIDefinitionByIdDto) => { diff --git a/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.types.ts b/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.types.ts index 33a92dacbb..93c4b7d9f0 100644 --- a/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.types.ts +++ b/apps/workflows-dashboard/src/domains/ui-definitions/ui-definitions.types.ts @@ -13,6 +13,8 @@ export interface IUIDefinition { uiSchema: IUISchema; locales?: object; createdAt: string; + name: string; + theme?: object; } export interface UpdateUIDefinitionDto { @@ -23,6 +25,7 @@ export interface UpdateUIDefinitionDto { export interface CopyUIDefinitionDto { uiDefinitionId: string; + name: string; } export interface GetUIDefinitionByIdDto { uiDefinitionId: string; diff --git a/apps/workflows-dashboard/src/pages/Filters/Filters.tsx b/apps/workflows-dashboard/src/pages/Filters/Filters.tsx index c6a00a8298..f59428f852 100644 --- a/apps/workflows-dashboard/src/pages/Filters/Filters.tsx +++ b/apps/workflows-dashboard/src/pages/Filters/Filters.tsx @@ -9,15 +9,165 @@ import { useFiltersQuery } from '@/pages/Filters/hooks/useFiltersQuery'; import { FiltersPageFilterValues } from '@/pages/Filters/types/filters-filter-values'; import { WorkflowsLayout } from '@/pages/Workflows/components/layouts/WorkflowsLayout'; import { NumberParam, withDefault } from 'use-query-params'; +import { Button } from '@/components/atoms/Button'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from '@/components/atoms/Dialog'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/atoms/Select'; +import { Input } from '@/components/atoms/Input'; +import { useState } from 'react'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useWorkflowDefinitionsQuery } from '../WorkflowDefinitions/hooks/useWorkflowDefinitionsQuery'; +import { createFilter } from '@/domains/filters/filters.api'; +import { CreateFilterDto } from '@/domains/filters/filters.types'; export const Filters = withFilters, FiltersPageFilterValues>( ({ filters }) => { const { data, isLoading } = useFiltersQuery(filters); const { handlePageChange, page, total } = useFiltersPagePagination(); + const [isOpen, setIsOpen] = useState(false); + const [filterName, setFilterName] = useState(''); + const [selectedWorkflow, setSelectedWorkflow] = useState(''); + + const { data: workflowDefinitions } = useWorkflowDefinitionsQuery(); + + const queryClient = useQueryClient(); + + const createFilterMutation = useMutation({ + mutationFn: async (data: CreateFilterDto) => { + return await createFilter(data); + }, + onSuccess: () => { + void queryClient.invalidateQueries({ queryKey: ['filters'] }); + setIsOpen(false); + setFilterName(''); + setSelectedWorkflow(''); + }, + }); + + const handleSubmit = () => { + if (!filterName || !selectedWorkflow) return; + + createFilterMutation.mutate({ + name: filterName, + entity: 'businesses', + projectId: data?.items[0]?.projectId ?? '', + query: { + where: { + businessId: { + not: null, + }, + workflowDefinitionId: { + in: [selectedWorkflow], + }, + }, + select: { + id: true, + tags: true, + state: true, + status: true, + context: true, + assignee: { + select: { + id: true, + lastName: true, + avatarUrl: true, + firstName: true, + }, + }, + business: { + select: { + id: true, + email: true, + address: true, + website: true, + industry: true, + createdAt: true, + documents: true, + legalForm: true, + updatedAt: true, + vatNumber: true, + companyName: true, + phoneNumber: true, + approvalState: true, + businessPurpose: true, + numberOfEmployees: true, + registrationNumber: true, + dateOfIncorporation: true, + shareholderStructure: true, + countryOfIncorporation: true, + taxIdentificationNumber: true, + }, + }, + createdAt: true, + assigneeId: true, + workflowDefinition: { + select: { + id: true, + name: true, + config: true, + version: true, + definition: true, + contextSchema: true, + documentsSchema: true, + }, + }, + childWorkflowsRuntimeData: true, + }, + }, + }); + }; return ( +
+ + + + + + + Create New Filter + +
+ setFilterName(e.target.value)} + /> + + +
+
+
+
diff --git a/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/FiltersTable.tsx b/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/FiltersTable.tsx index 3180dc1f3b..6286ba5dbb 100644 --- a/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/FiltersTable.tsx +++ b/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/FiltersTable.tsx @@ -21,6 +21,7 @@ interface Props { onSort?: (key: string, direction: 'asc' | 'desc') => void; } +// eslint-disable-next-line react/display-name export const FiltersTable = memo(({ items, isFetching, sorting, onSort }: Props) => { const table = useReactTable({ columns: filtersTableColumns, diff --git a/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/columns.tsx b/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/columns.tsx index 26100d12b3..3a10e14bed 100644 --- a/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/columns.tsx +++ b/apps/workflows-dashboard/src/pages/Filters/components/FiltersTable/columns.tsx @@ -3,35 +3,89 @@ import { IFilter } from '@/domains/filters'; import { formatDate } from '@/utils/format-date'; import { createColumnHelper } from '@tanstack/react-table'; import { Eye } from 'lucide-react'; +import { valueOrNA } from '@/utils/value-or-na'; +import { toast } from 'sonner'; const columnHelper = createColumnHelper(); export const filtersTableColumns = [ columnHelper.accessor('id', { - cell: info => info.getValue(), - header: () => 'ID', + cell: info => ( +
+ {info.getValue()} + +
+ ), + header: () => ID, }), columnHelper.accessor('name', { - cell: info => info.getValue(), - header: () => 'Name', + cell: info => {info.getValue()}, + header: () => Name, }), columnHelper.accessor('entity', { - cell: info => info.getValue(), - header: () => 'Entity', + cell: info => ( + + {valueOrNA(info.getValue())} + + ), + header: () => Entity, }), columnHelper.accessor('query', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} />
), - header: () => 'Definition', + header: () => Definition, }), + columnHelper.accessor( + row => { + const query = row.query as { where?: { workflowDefinitionId?: { in?: string[] } } }; + return query.where?.workflowDefinitionId?.in?.[0] ?? ''; + }, + { + id: 'workflowDefinitionId', + cell: info => ( + + {valueOrNA(info.getValue())} + + ), + header: () => Workflow ID, + }, + ), columnHelper.accessor('createdAt', { - cell: info => formatDate(info.getValue()), - header: () => 'Created At', + cell: info => {formatDate(info.getValue())}, + header: () => Created At, }), ]; diff --git a/apps/workflows-dashboard/src/pages/Filters/helpers/deserialize-query-params.ts b/apps/workflows-dashboard/src/pages/Filters/helpers/deserialize-query-params.ts index 190998e424..d7734092ad 100644 --- a/apps/workflows-dashboard/src/pages/Filters/helpers/deserialize-query-params.ts +++ b/apps/workflows-dashboard/src/pages/Filters/helpers/deserialize-query-params.ts @@ -5,6 +5,7 @@ export const deserializeQueryParams = (query: FiltersPageFilterQuery) => { const filters: FiltersPageFilterValues = { page: query.page as number, limit: query.limit as number, + projectId: query.projectId as string, }; return filters; diff --git a/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/index.ts b/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/index.ts new file mode 100644 index 0000000000..44a7c0e402 --- /dev/null +++ b/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/index.ts @@ -0,0 +1 @@ +export * from './useCreateFilterMutation'; diff --git a/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/useCreateFilterMutation.ts b/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/useCreateFilterMutation.ts new file mode 100644 index 0000000000..9847242e7e --- /dev/null +++ b/apps/workflows-dashboard/src/pages/Filters/hooks/useCreateFilterMutation/useCreateFilterMutation.ts @@ -0,0 +1,16 @@ +import { filtersQueryKeys, GetFiltersListDto } from '@/domains/filters'; +import { useQuery } from '@tanstack/react-query'; + +export const useFiltersQuery = (query: GetFiltersListDto) => { + const { isLoading, data } = useQuery({ + ...filtersQueryKeys.list(query), + // @ts-ignore + retry: false, + keepPreviousData: true, + }); + + return { + isLoading, + data, + }; +}; diff --git a/apps/workflows-dashboard/src/pages/Filters/types/filters-filter-values.ts b/apps/workflows-dashboard/src/pages/Filters/types/filters-filter-values.ts index 98170b2c69..3b9a2283e0 100644 --- a/apps/workflows-dashboard/src/pages/Filters/types/filters-filter-values.ts +++ b/apps/workflows-dashboard/src/pages/Filters/types/filters-filter-values.ts @@ -1,4 +1,5 @@ export interface FiltersPageFilterValues { + projectId: string; page: number; limit: number; } diff --git a/apps/workflows-dashboard/src/pages/Filters/types/filters-query-params.ts b/apps/workflows-dashboard/src/pages/Filters/types/filters-query-params.ts index 2c8d92c3c4..44fe641574 100644 --- a/apps/workflows-dashboard/src/pages/Filters/types/filters-query-params.ts +++ b/apps/workflows-dashboard/src/pages/Filters/types/filters-query-params.ts @@ -1,4 +1,5 @@ export interface FiltersPageFilterQuery { + projectId: string; page?: number; limit?: number; } diff --git a/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/columns.tsx b/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/columns.tsx index 2cbf3b57eb..c498456e04 100644 --- a/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/columns.tsx +++ b/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/columns.tsx @@ -2,75 +2,132 @@ import { JSONViewButton } from '@/components/molecules/JSONViewButton'; import { IUIDefinition } from '@/domains/ui-definitions'; import { CloneUIDefinitionButton } from '@/pages/UIDefinitions/components/UIDefinitionsTable/components/CloneUIDefinitionButton'; import { formatDate } from '@/utils/format-date'; +import { valueOrNA } from '@/utils/value-or-na'; import { createColumnHelper } from '@tanstack/react-table'; import { ArrowRightCircleIcon, Eye } from 'lucide-react'; import { Link } from 'react-router-dom'; +import { toast } from 'sonner'; const columnHelper = createColumnHelper(); export const uiDefinitionTableColumnns = [ columnHelper.accessor('id', { - cell: info => info.getValue(), - header: () => 'ID', + cell: info => ( +
+ {info.getValue()} + +
+ ), + header: () => ID, }), - columnHelper.accessor('workflowDefinitionId', { - cell: info => info.getValue(), - header: () => 'Workflow Definition ID', + columnHelper.accessor('name', { + cell: info => {info.getValue()}, + header: () => Name, }), + columnHelper.accessor('uiContext', { - cell: info => info.getValue(), - header: () => 'UI Context', + cell: info => ( + + {info.getValue()} + + ), + header: () => UI Context, }), columnHelper.accessor('definition', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} />
), - header: () => 'Definition', + header: () => Definition, }), columnHelper.accessor('uiSchema', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} />
), - header: () => 'UI Schema', + header: () => UI Schema, }), columnHelper.accessor('locales', { cell: info => { const locales = info.getValue() ? JSON.stringify(info.getValue()) : null; return ( -
+
{locales ? ( - } json={locales} /> + + } + json={locales} + /> ) : ( - 'N/A' + N/A )}
); }, - header: () => 'Translations', + header: () => Translations, + }), + columnHelper.accessor('workflowDefinitionId', { + cell: info => ( + {valueOrNA(info.getValue())} + ), + header: () => Default Workflow Definition ID, }), columnHelper.accessor('createdAt', { - cell: info => formatDate(info.getValue()), - header: () => 'Created At', + cell: info => {formatDate(info.getValue())}, + header: () => Created At, }), columnHelper.accessor('id', { - cell: info => , + cell: info => ( +
+ +
+ ), header: () => '', }), columnHelper.accessor('id', { cell: info => ( - - + + ), header: () => '', diff --git a/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/components/CloneUIDefinitionButton/CloneUIDefinitionButton.tsx b/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/components/CloneUIDefinitionButton/CloneUIDefinitionButton.tsx index 335e44ab10..84ed17d53a 100644 --- a/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/components/CloneUIDefinitionButton/CloneUIDefinitionButton.tsx +++ b/apps/workflows-dashboard/src/pages/UIDefinitions/components/UIDefinitionsTable/components/CloneUIDefinitionButton/CloneUIDefinitionButton.tsx @@ -1,6 +1,26 @@ import { Button } from '@/components/atoms/Button'; +import { Dialog, DialogContent, DialogTrigger } from '@/components/atoms/Dialog'; import { useCloneUIDefinitionMutation } from '@/pages/UIDefinitions/hooks/useCloneUIDefinitionMutation'; -import { FunctionComponent } from 'react'; +import { DynamicForm } from '@ballerine/ui'; +import { RJSFSchema } from '@rjsf/utils'; +import { FunctionComponent, useCallback, useEffect, useState } from 'react'; + +const formSchema = { + type: 'object', + required: ['name'], + properties: { + name: { + type: 'string', + title: 'Name', + }, + }, +}; + +const uiSchema = { + name: { + 'ui:placeholder': 'Enter name', + }, +}; interface ICLoneUIDefinitionButtonProps { uiDefinitionId: string; @@ -9,11 +29,36 @@ interface ICLoneUIDefinitionButtonProps { export const CloneUIDefinitionButton: FunctionComponent = ({ uiDefinitionId, }) => { - const { mutate, isLoading } = useCloneUIDefinitionMutation(); + const [isDialogOpen, setIsDialogOpen] = useState(false); + const { mutate, isLoading, isSuccess } = useCloneUIDefinitionMutation(); + + const handleSubmit = useCallback( + async (formData: Record) => { + const values: { name: string } = formData as any; + mutate({ uiDefinitionId, ...values }); + }, + [uiDefinitionId, mutate], + ); + + useEffect(() => { + if (isSuccess) { + setIsDialogOpen(false); + } + }, [isSuccess]); return ( - + + + + + + + + ); }; diff --git a/apps/workflows-dashboard/src/pages/UIDefinitions/helpers/deserialize-query-params.ts b/apps/workflows-dashboard/src/pages/UIDefinitions/helpers/deserialize-query-params.ts index 190998e424..d7734092ad 100644 --- a/apps/workflows-dashboard/src/pages/UIDefinitions/helpers/deserialize-query-params.ts +++ b/apps/workflows-dashboard/src/pages/UIDefinitions/helpers/deserialize-query-params.ts @@ -5,6 +5,7 @@ export const deserializeQueryParams = (query: FiltersPageFilterQuery) => { const filters: FiltersPageFilterValues = { page: query.page as number, limit: query.limit as number, + projectId: query.projectId as string, }; return filters; diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinition/WorkflowDefinition.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinition/WorkflowDefinition.tsx index 2644ed8f53..d8d20b40cf 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinition/WorkflowDefinition.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinition/WorkflowDefinition.tsx @@ -13,6 +13,44 @@ import { useWorkflowDefinitionExtensionsEdit } from '@/pages/WorkflowDefinition/ import { ViewWorkflow } from '@/pages/Workflows/components/organisms/WorkflowsList/components/ViewWorkflow'; import { isAxiosError } from 'axios'; import { Link, useParams } from 'react-router-dom'; +import { Dialog } from '@/components/atoms/Dialog'; +import { useState } from 'react'; +import { Button } from '@/components/atoms/Button'; + +export const VENDOR_DETAILS = { + 'dow-jones': { + logoUrl: 'https://cdn.ballerine.io/logos/Dow_Jones_Logo.png', + description: 'Dow Jones provides sanctions screening and risk data for individuals', + }, + 'comply-advantage': { + logoUrl: 'https://cdn.ballerine.io/logos/comply-advantage-logo.png', + description: + 'ComplyAdvantage offers AI-driven sanctions screening and monitoring for individuals', + }, + 'asia-verify': { + logoUrl: 'https://cdn.ballerine.io/logos/AsiaVerify_Logo.png', + description: + 'AsiaVerify provides company screening, UBO verification and registry information services focused on APAC region', + }, + veriff: { + logoUrl: 'https://cdn.ballerine.io/logos/Veriff_logo.svg.png', + description: 'Veriff provides KYC verification and identity proofing services', + }, + ballerine: { + logoUrl: 'https://cdn.ballerine.io/logos/ballerine-logo.png', + description: 'Ballerine provides merchant monitoring services', + }, + kyckr: { + logoUrl: 'https://cdn.ballerine.io/logos/kyckr-logo.png', + description: 'Kyckr provides UBO verification and company registry information services', + }, + test: { + logoUrl: 'https://cdn.ballerine.io/logos/ballerine-logo.png', + description: 'Test vendor for development purposes', + }, +} as const; + +export type VendorId = keyof typeof VENDOR_DETAILS; export const WorkflowDefinition = () => { const id = useParams<{ id: string }>().id; @@ -22,6 +60,11 @@ export const WorkflowDefinition = () => { useWorkflowDefinitionExtensionsEdit(data); const { mutate: upgradeWorkflowDefinitionVersion } = useUpgradeWorkflowDefinitionVersionMutation(); + const [isIntegrationCatalogOpen, setIsIntegrationCatalogOpen] = useState(false); + + const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text); + }; if (isLoading) { return ( @@ -58,66 +101,291 @@ export const WorkflowDefinition = () => { if (!data) return null; return ( - -
-
-
- - - X-State Visualizer - - - - - - -
-
- -
-
-
-
- + <> + +
+
+
+ + +

X-State Visualizer

+ +
+ + + +
+
+
+ +
-
- { - console.log('changed value', value); - }} - onUpgrade={() => upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! })} - /> +
+
+ +
+
+ { + console.log('changed value', value); + }} + onUpgrade={() => + upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! }) + } + /> +
-
-
-
- upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! })} - /> -
-
- { - console.log('changed value', value); - }} - onUpgrade={() => upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! })} - /> +
+
+ + upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! }) + } + enableViewMode={true} + viewDialogContent={ +
+
+ +
+ {isIntegrationCatalogOpen && ( +
+ +
+
+
+

Integration Catalog

+ +
+
+ {Object.entries(VENDOR_DETAILS).map(([vendorKey, vendorInfo]) => ( +
+
+
+ {vendorKey} { + e.currentTarget.src = + 'https://cdn.ballerine.io/logos/ballerine-logo.png'; + }} + /> +
+
+
+

+ {vendorKey + .split('-') + .map( + word => + word.charAt(0).toUpperCase() + word.slice(1), + ) + .join(' ')} +

+ +
+

+ {vendorInfo.description} +

+
+
+
+ ))} +
+
+
+
+
+ )} + {Object.entries(workflowDefinitionExtensions || {}).map( + ([category, plugins]) => ( +
+

+
+ {category + .split(/(?=[A-Z])/) + .join(' ') + .replace('Plugins', '') + .replace(/^\w/, c => c.toUpperCase())}{' '} + Plugins +

+
+ {(plugins as any[]).map(plugin => ( +
+
+
+ {plugin.vendor === 'test' ? ( +
+ + Test + +
+ ) : plugin.vendor ? ( + {plugin.vendor} { + e.currentTarget.src = + 'https://cdn.ballerine.io/logos/ballerine-logo.png'; + }} + /> + ) : ( + Ballerine + )} +
+
+

+ {(plugin.displayName || plugin.name) + .split(/(?=[A-Z])/) + .join(' ')} +

+
+

+ {plugin.pluginKind} +

+ {plugin.vendor && ( +

+ by {plugin.vendor} +

+ )} +
+
+
+ + {plugin.stateNames?.length > 0 && ( +
+ {plugin.stateNames?.map((state: string) => ( + + {state} + + ))} +
+ )} + +
+ {plugin.successAction && ( +
+ Success: + + {plugin.successAction} + +
+ )} + + {plugin.errorAction && ( +
+ Error: + + {plugin.errorAction} + +
+ )} +
+
+ ))} +
+
+ ), + )} +
+ } + /> +
+
+ { + console.log('changed value', value); + }} + onUpgrade={() => + upgradeWorkflowDefinitionVersion({ workflowDefinitionId: data.id! }) + } + /> +
-
- + + ); }; diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/EditorCard/EditorCard.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/EditorCard/EditorCard.tsx index 2b0b2b56ad..d645f81215 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/EditorCard/EditorCard.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/EditorCard/EditorCard.tsx @@ -2,30 +2,46 @@ import { Button } from '@/components/atoms/Button'; import { Card, CardContent, CardHeader } from '@/components/atoms/Card'; import { Dialog, DialogContent, DialogTrigger } from '@/components/atoms/Dialog'; import { JSONEditorComponent } from '@/components/organisms/JsonEditor'; -import { Pencil } from 'lucide-react'; +import { Code, Eye, Pencil } from 'lucide-react'; import { FunctionComponent, useCallback, useEffect, useMemo, useState } from 'react'; interface IEditorCardProps { value: object; title: string; dialogContent?: React.ReactNode | React.ReactNode[]; + viewDialogContent?: React.ReactNode; + rawEditDialogContent?: React.ReactNode; + noCodeDialogContent?: React.ReactNode; onChange?: (value: object) => void; onSave?: (value: object) => void; onOpenChange?: (open: boolean) => void; onUpgrade?: () => void; } -export const EditorCard: FunctionComponent = ({ +export const EditorCard: FunctionComponent< + IEditorCardProps & { + enableViewMode?: boolean; + enableNoCodeMode?: boolean; + } +> = ({ value, title, dialogContent, + viewDialogContent, + rawEditDialogContent, + noCodeDialogContent, onChange, onSave, onOpenChange, onUpgrade, + enableViewMode = false, + enableNoCodeMode = false, }) => { const [valueSnapshot, setSnapshot] = useState(value); const [internalValue, setInternalValue] = useState(valueSnapshot); + const [dialogMode, setDialogMode] = useState<'view' | 'raw-edit' | 'no-code' | undefined>( + undefined, + ); useEffect(() => { setInternalValue(value); @@ -38,58 +54,154 @@ export const EditorCard: FunctionComponent = ({ const handleChange = useCallback( (value: object) => { setInternalValue(value); - onChange && onChange(value); + onChange?.(value); }, [onChange], ); const handleSave = useCallback(() => { setSnapshot(internalValue); - onSave && onSave(internalValue); + onSave?.(internalValue); }, [internalValue, onSave]); + const renderDialogContent = () => { + if (dialogContent) return dialogContent; + + switch (dialogMode) { + case 'view': + return ( + + {viewDialogContent ? ( + viewDialogContent + ) : ( +
+
+ +
+
+ )} +
+ ); + + case 'raw-edit': + return ( + + {rawEditDialogContent ? ( + rawEditDialogContent + ) : ( +
+
+ +
+ {onSave && ( +
+ + +
+ )} +
+ )} +
+ ); + + case 'no-code': + return ( + + {noCodeDialogContent ? ( + noCodeDialogContent + ) : ( +
+
+ {/* TODO: Implement no-code editor UI */} +
No-code editor coming soon
+
+ {onSave && ( +
+ + +
+ )} +
+ )} +
+ ); + + default: + return null; + } + }; + return ( { if (!open) { setSnapshot(value); setInternalValue(value); + setDialogMode(undefined); } - onOpenChange && onOpenChange(open); + + onOpenChange?.(open); }} > - - - {title} - - - + + + {title} +
+ enableViewMode && setDialogMode('view')} + > + + + + enableNoCodeMode && setDialogMode('no-code')} + > + + + setDialogMode('raw-edit')}> + - +
- +
- {dialogContent ? ( - dialogContent - ) : ( - -
-
- -
- {onSave && ( -
- - -
- )} -
-
- )} + + {renderDialogContent()}
); }; diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/UIDefinitionEditor/UIDefinitionEditor.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/UIDefinitionEditor/UIDefinitionEditor.tsx index 3f9b41e5d3..34d546ff20 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/UIDefinitionEditor/UIDefinitionEditor.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/UIDefinitionEditor/UIDefinitionEditor.tsx @@ -31,46 +31,194 @@ export const UIDefinitionEditor: FunctionComponent = ({ reset(); } }} - dialogContent={ - - - - All - {uiSchema.elements.map(element => { - return ( - - {element.stateName} - - ); - })} - - - - + enableViewMode={true} + viewDialogContent={ +
+
+ {uiDefinition.uiSchema.elements.map((element: any, index: number) => ( +
+
+
+
+ + {index + 1} + +

{element.name}

+
+

State: {element.stateName}

+
+
+ +
+ {element.elements?.length > 0 && ( +
+

Form Elements

+
+ {element.elements.map((el: any, i: number) => { + // Helper function to render form elements + const renderFormElement = (element: any) => { + if (!element.type?.startsWith('json-form:')) return null; + + const valueDestination = element.valueDestination?.split('.')?.pop(); + + return ( +
+
+ {valueDestination || element.name || element.type} +
+ {element.options?.label && ( +
+ {element.options.label} +
+ )} +
+ ); + }; + + // Handle direct json-form elements + if (el.type?.startsWith('json-form:')) { + return
{renderFormElement(el)}
; + } + + // Handle nested elements + if (el.elements) { + return ( +
+ {el.elements.map((nestedEl: any, j: number) => { + if (nestedEl.type?.startsWith('json-form:')) { + return
{renderFormElement(nestedEl)}
; + } + + // Recursively check deeper nested elements + if (nestedEl.elements) { + return nestedEl.elements.map((deepEl: any, k: number) => { + if (deepEl.type?.startsWith('json-form:')) { + return ( +
{renderFormElement(deepEl)}
+ ); + } + + return null; + }); + } + + return null; + })} +
+ ); + } + + return null; + })} +
+
+ )} + + {element.actions?.length > 0 && ( +
+

Actions

+
+ {element.actions.map((action: any, i: number) => ( +
+
+ {action.type} + {action.params && ( + + {action.params.eventName || action.params.pluginName} + + )} +
+
+ ))} +
+
+ )} + + {element.pageValidation?.length > 0 && ( +
+

Validations

+
+ {element.pageValidation.map((validation: any, i: number) => ( +
+
+ {validation.type} +
+
+ ))} +
+
+ )} +
+
+ ))} +
+
+ } + rawEditDialogContent={ + + + All {uiSchema.elements.map(element => { return ( - - - + + {element.stateName} + ); })} -
- - -
-
-
+ theme + locales + + + + + {uiSchema.elements.map(element => { + return ( + + + + ); + })} + + + handleUIDefinitionChange({ + ...uiDefinitionValue, + theme: value, + }) + } + /> + + + + handleUIDefinitionChange({ + ...uiDefinitionValue, + locales: value, + }) + } + /> + +
+ + +
+ } /> ); diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/WorkflowDefinitionSummaryCard/WorkflowDefinitionSummaryCard.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/WorkflowDefinitionSummaryCard/WorkflowDefinitionSummaryCard.tsx index 9aff7dad85..e3dc8d42be 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/WorkflowDefinitionSummaryCard/WorkflowDefinitionSummaryCard.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinition/components/WorkflowDefinitionSummaryCard/WorkflowDefinitionSummaryCard.tsx @@ -2,6 +2,7 @@ import { Card, CardContent, CardHeader } from '@/components/atoms/Card'; import { IWorkflowDefinition } from '@/domains/workflow-definitions'; import { valueOrNA } from '@/utils/value-or-na'; import { FunctionComponent } from 'react'; +import dayjs from 'dayjs'; interface IWorkflowDefinitionSummaryCardProps { workflowDefinition: IWorkflowDefinition; @@ -11,39 +12,42 @@ export const WorkflowDefinitionSummaryCard: FunctionComponent< IWorkflowDefinitionSummaryCardProps > = ({ workflowDefinition }) => { return ( - - - Summary + + +

Workflow Summary

- -
- ID: - {workflowDefinition.id} -
-
- Name: - {workflowDefinition.name} -
-
- Display Name: - {valueOrNA(workflowDefinition.displayName)} -
-
- Version: - {valueOrNA(workflowDefinition.version)} -
-
- Variant: - {valueOrNA(workflowDefinition.variant)} -
-
- Created At: - {new Date(workflowDefinition.createdAt as string).toISOString()} -
-
- Is Public: - {workflowDefinition.isPublic ? 'Yes' : 'No'} -
+ + {[ + { label: 'ID', value: workflowDefinition.id }, + { label: 'Name', value: workflowDefinition.name }, + { label: 'Display Name', value: valueOrNA(workflowDefinition.displayName) }, + { label: 'Version', value: valueOrNA(workflowDefinition.version) }, + { label: 'Variant', value: valueOrNA(workflowDefinition.variant) }, + { + label: 'Created At', + value: dayjs(workflowDefinition.createdAt).format('MMM D, YYYY h:mm A'), + }, + { + label: 'Is Public', + value: workflowDefinition.isPublic ? ( + + Yes + + ) : ( + + No + + ), + }, + ].map(({ label, value }, index) => ( +
+ {label} + {value} +
+ ))}
); diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/WorkflowDefinitionsTable.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/WorkflowDefinitionsTable.tsx index 0a2cb08639..3b54eed9ad 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/WorkflowDefinitionsTable.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/WorkflowDefinitionsTable.tsx @@ -117,3 +117,5 @@ export const WorkflowDefinitionsTable = memo(({ items, isFetching, sorting, onSo
); }); + +WorkflowDefinitionsTable.displayName = 'WorkflowDefinitionsTable'; diff --git a/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/columns.tsx b/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/columns.tsx index 4ba6410762..da02387dac 100644 --- a/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/columns.tsx +++ b/apps/workflows-dashboard/src/pages/WorkflowDefinitions/components/molecules/WorkflowDefinitionsTable/columns.tsx @@ -5,84 +5,152 @@ import { valueOrNA } from '@/utils/value-or-na'; import { createColumnHelper } from '@tanstack/react-table'; import { ArrowRightCircleIcon, Eye, Pencil } from 'lucide-react'; import { Link } from 'react-router-dom'; +import { toast } from 'sonner'; const columnHelper = createColumnHelper(); export const workflowDefinitionsTableColumns = [ columnHelper.accessor('id', { - cell: info => info.getValue(), - header: () => 'ID', + cell: info => ( +
+ {info.getValue()} + +
+ ), + header: () => ID, }), columnHelper.accessor('name', { - cell: info => info.getValue(), - header: () => 'Name', + cell: info => {info.getValue()}, + header: () => Name, }), columnHelper.accessor('displayName', { - cell: info => valueOrNA(info.getValue()), - header: () => 'Display Name', + cell: info => {valueOrNA(info.getValue())}, + header: () => Display Name, + }), + columnHelper.accessor('isPublic', { + cell: info => ( + () + ? 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200' + : 'bg-slate-100 text-slate-700 hover:bg-slate-200' + }`} + > + {info.getValue() ? 'Public' : 'Private'} + + ), + header: () => Visibility, }), columnHelper.accessor('definitionType', { - cell: info => info.getValue(), - header: () => 'Definition Type', + cell: info => ( + + {info.getValue()} + + ), + header: () => Definition Type, }), columnHelper.accessor('variant', { - cell: info => info.getValue(), - header: () => 'Variant', + cell: info => ( + + {info.getValue()} + + ), + header: () => Variant, }), columnHelper.accessor('definition', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} /> - +
), - header: () => 'Definition', + header: () => Definition, }), columnHelper.accessor('contextSchema', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} /> - +
), - header: () => 'Context Schema', + header: () => Context Schema, }), columnHelper.accessor('config', { cell: info => ( -
+
} + trigger={ + + } json={JSON.stringify(info.getValue())} /> - +
), - header: () => 'Config', + header: () => Config, }), columnHelper.accessor('version', { - cell: info => info.getValue(), - header: () => 'Version', + cell: info => ( + + v{info.getValue()} + + ), + header: () => Version, }), columnHelper.accessor('id', { - cell: info => , + cell: info => ( +
+ +
+ ), header: () => '', }), columnHelper.accessor('id', { cell: info => ( - - + + ), header: () => '', diff --git a/examples/headless-example/CHANGELOG.md b/examples/headless-example/CHANGELOG.md index e9ea9663f0..fe70c47c47 100644 --- a/examples/headless-example/CHANGELOG.md +++ b/examples/headless-example/CHANGELOG.md @@ -1,5 +1,20 @@ # @ballerine/headless-example +## 0.3.76 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + - @ballerine/workflow-browser-sdk@0.6.77 + +## 0.3.75 + +### Patch Changes + +- @ballerine/workflow-browser-sdk@0.6.76 + ## 0.3.74 ### Patch Changes diff --git a/examples/headless-example/package.json b/examples/headless-example/package.json index fb203657e0..9f33151a1b 100644 --- a/examples/headless-example/package.json +++ b/examples/headless-example/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/headless-example", "private": true, - "version": "0.3.74", + "version": "0.3.76", "type": "module", "scripts": { "spellcheck": "cspell \"*\"", @@ -34,8 +34,8 @@ "vite": "^4.5.3" }, "dependencies": { - "@ballerine/common": "0.9.57", - "@ballerine/workflow-browser-sdk": "0.6.75", + "@ballerine/common": "0.9.58", + "@ballerine/workflow-browser-sdk": "0.6.77", "@felte/reporter-svelte": "^1.1.5", "@felte/validator-zod": "^1.0.13", "@fontsource/inter": "^4.5.15", diff --git a/examples/report-generation-example/CHANGELOG.md b/examples/report-generation-example/CHANGELOG.md index a4e1553975..ccf6d6e41b 100644 --- a/examples/report-generation-example/CHANGELOG.md +++ b/examples/report-generation-example/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/report-generation-example +## 0.2.26 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/react-pdf-toolkit@1.2.50 + ## 0.2.25 ### Patch Changes diff --git a/examples/report-generation-example/package.json b/examples/report-generation-example/package.json index 32bfd336f7..388e8c8f1f 100644 --- a/examples/report-generation-example/package.json +++ b/examples/report-generation-example/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/report-generation-example", "private": false, - "version": "0.2.25", + "version": "0.2.26", "type": "module", "scripts": { "dev": "vite", @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@ballerine/react-pdf-toolkit": "^1.2.48", + "@ballerine/react-pdf-toolkit": "^1.2.50", "react": "^18.2.0", "react-dom": "^18.2.0" }, diff --git a/packages/blocks/CHANGELOG.md b/packages/blocks/CHANGELOG.md index 2e7d4dde98..62c93f0354 100644 --- a/packages/blocks/CHANGELOG.md +++ b/packages/blocks/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/blocks +## 0.2.29 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + ## 0.2.28 ### Patch Changes diff --git a/packages/blocks/package.json b/packages/blocks/package.json index 4a8042d7b1..08aaaad59b 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -2,7 +2,7 @@ "private": false, "name": "@ballerine/blocks", "author": "Ballerine ", - "version": "0.2.28", + "version": "0.2.29", "description": "blocks", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -42,8 +42,8 @@ "@babel/preset-env": "7.16.11", "@babel/preset-react": "^7.22.5", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config": "^1.1.27", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-json": "^6.0.0", @@ -91,6 +91,6 @@ "vitest": "^0.33.0" }, "dependencies": { - "@ballerine/common": "^0.9.55" + "@ballerine/common": "^0.9.58" } } diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 253268d018..3b649c5132 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/common +## 0.9.58 + +### Patch Changes + +- Bump + ## 0.9.57 ### Patch Changes diff --git a/packages/common/package.json b/packages/common/package.json index c4212a1d93..1c738eb968 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -2,7 +2,7 @@ "private": false, "name": "@ballerine/common", "author": "Ballerine ", - "version": "0.9.57", + "version": "0.9.58", "description": "common", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -38,8 +38,8 @@ "@babel/core": "7.17.9", "@babel/preset-env": "7.16.11", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", diff --git a/packages/config/CHANGELOG.md b/packages/config/CHANGELOG.md index 025ad3614a..0308545f0e 100644 --- a/packages/config/CHANGELOG.md +++ b/packages/config/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/config +## 1.1.27 + +### Patch Changes + +- Bump + ## 1.1.26 ### Patch Changes diff --git a/packages/config/package.json b/packages/config/package.json index c29dd59406..34febe082b 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -1,7 +1,7 @@ { "private": false, "name": "@ballerine/config", - "version": "1.1.26", + "version": "1.1.27", "description": "", "main": "index.js", "scripts": {}, diff --git a/packages/eslint-config-react/CHANGELOG.md b/packages/eslint-config-react/CHANGELOG.md index 633953c0e0..c90b954605 100644 --- a/packages/eslint-config-react/CHANGELOG.md +++ b/packages/eslint-config-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/eslint-config-react +## 2.0.27 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/eslint-config@1.1.27 + ## 2.0.26 ### Patch Changes diff --git a/packages/eslint-config-react/package.json b/packages/eslint-config-react/package.json index a0f11d87fd..b459b25f27 100644 --- a/packages/eslint-config-react/package.json +++ b/packages/eslint-config-react/package.json @@ -1,7 +1,7 @@ { "private": false, "name": "@ballerine/eslint-config-react", - "version": "2.0.26", + "version": "2.0.27", "description": "", "main": "index.js", "scripts": {}, @@ -10,7 +10,7 @@ "license": "ISC", "peerDependencies": { "eslint-plugin-react": "^7.33.2", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/eslint-config": "^1.1.27", "eslint-plugin-react-hooks": "^4.6.0" } } diff --git a/packages/eslint-config/CHANGELOG.md b/packages/eslint-config/CHANGELOG.md index 000f31120f..552473a0cf 100644 --- a/packages/eslint-config/CHANGELOG.md +++ b/packages/eslint-config/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/eslint-config +## 1.1.27 + +### Patch Changes + +- Bump + ## 1.1.26 ### Patch Changes diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index d26db10f3c..712462dcc3 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,7 +1,7 @@ { "private": false, "name": "@ballerine/eslint-config", - "version": "1.1.26", + "version": "1.1.27", "description": "", "main": "index.js", "scripts": {}, diff --git a/packages/react-pdf-toolkit/CHANGELOG.md b/packages/react-pdf-toolkit/CHANGELOG.md index 4bdf41f0d6..685a9a1fe4 100644 --- a/packages/react-pdf-toolkit/CHANGELOG.md +++ b/packages/react-pdf-toolkit/CHANGELOG.md @@ -1,5 +1,14 @@ # @ballerine/react-pdf-toolkit +## 1.2.50 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/config@1.1.27 + - @ballerine/ui@0.5.50 + ## 1.2.49 ### Patch Changes diff --git a/packages/react-pdf-toolkit/package.json b/packages/react-pdf-toolkit/package.json index aed3624c1b..1d6861ccaa 100644 --- a/packages/react-pdf-toolkit/package.json +++ b/packages/react-pdf-toolkit/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/react-pdf-toolkit", "private": false, - "version": "1.2.49", + "version": "1.2.50", "types": "./dist/build.d.ts", "main": "./dist/react-pdf-toolkit.js", "module": "./dist/react-pdf-toolkit.mjs", @@ -26,8 +26,8 @@ "build-storybook": "storybook build" }, "dependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/ui": "0.5.49", + "@ballerine/config": "^1.1.27", + "@ballerine/ui": "0.5.50", "@react-pdf/renderer": "^3.1.14", "@sinclair/typebox": "^0.31.7", "ajv": "^8.12.0", diff --git a/packages/rules-engine/CHANGELOG.md b/packages/rules-engine/CHANGELOG.md index f82f3ab206..fd2c171a9e 100644 --- a/packages/rules-engine/CHANGELOG.md +++ b/packages/rules-engine/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/rules-engine-lib +## 0.5.27 + +### Patch Changes + +- Bump + ## 0.5.26 ### Patch Changes diff --git a/packages/rules-engine/package.json b/packages/rules-engine/package.json index 614a80eeaf..8e82449925 100644 --- a/packages/rules-engine/package.json +++ b/packages/rules-engine/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/rules-engine-lib", "author": "Ballerine ", - "version": "0.5.26", + "version": "0.5.27", "description": "rules-engine-lib", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -34,9 +34,9 @@ "@babel/core": "7.17.9", "@babel/preset-env": "7.16.11", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", + "@ballerine/config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/eslint-config": "^1.1.27", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-node-resolve": "13.2.1", diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md index 0d6dc272d5..c03b9ee462 100644 --- a/packages/ui/CHANGELOG.md +++ b/packages/ui/CHANGELOG.md @@ -1,5 +1,13 @@ # @ballerine/ui +## 0.5.50 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + ## 0.5.49 ### Patch Changes diff --git a/packages/ui/package.json b/packages/ui/package.json index 33e69dc746..f6337f48ec 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/ui", "private": false, - "version": "0.5.49", + "version": "0.5.50", "type": "module", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -26,7 +26,7 @@ "test": "vitest run" }, "dependencies": { - "@ballerine/common": "^0.9.55", + "@ballerine/common": "^0.9.58", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/material": "^5.14.2", @@ -65,8 +65,8 @@ "zod": "^3.23.4" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config-react": "^2.0.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config-react": "^2.0.27", "@cspell/cspell-types": "^6.31.1", "@storybook/addon-essentials": "^7.0.26", "@storybook/addon-interactions": "^7.0.26", diff --git a/packages/workflow-core/CHANGELOG.md b/packages/workflow-core/CHANGELOG.md index ade0f6ba63..76f7577b0f 100644 --- a/packages/workflow-core/CHANGELOG.md +++ b/packages/workflow-core/CHANGELOG.md @@ -1,5 +1,19 @@ # @ballerine/workflow-core +## 0.6.77 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + +## 0.6.76 + +### Patch Changes + +- Added no op event to workflow runner + ## 0.6.75 ### Patch Changes diff --git a/packages/workflow-core/package.json b/packages/workflow-core/package.json index 806b81f2ba..39ac9176cd 100644 --- a/packages/workflow-core/package.json +++ b/packages/workflow-core/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-core", "author": "Ballerine ", - "version": "0.6.75", + "version": "0.6.77", "description": "workflow-core", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -31,7 +31,7 @@ "node": ">=12" }, "dependencies": { - "@ballerine/common": "0.9.57", + "@ballerine/common": "0.9.58", "ajv": "^8.12.0", "country-state-city": "^3.1.4", "i18n-iso-countries": "^7.6.0", @@ -48,8 +48,8 @@ "@babel/core": "7.17.9", "@babel/preset-env": "7.16.11", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", diff --git a/packages/workflow-core/src/index.ts b/packages/workflow-core/src/index.ts index 36c539e90a..ecc62b1361 100644 --- a/packages/workflow-core/src/index.ts +++ b/packages/workflow-core/src/index.ts @@ -33,5 +33,6 @@ export { logger, setLogger, BUILT_IN_EVENT, + BUILT_IN_ACTION, ARRAY_MERGE_OPTION, } from './lib'; diff --git a/packages/workflow-core/src/lib/built-in-action.ts b/packages/workflow-core/src/lib/built-in-action.ts new file mode 100644 index 0000000000..e0d96f7673 --- /dev/null +++ b/packages/workflow-core/src/lib/built-in-action.ts @@ -0,0 +1,5 @@ +export const BUILT_IN_ACTION = { + NO_OP: 'NO_OP', +} as const; + +export type BuiltInAction = (typeof BUILT_IN_ACTION)[keyof typeof BUILT_IN_ACTION]; diff --git a/packages/workflow-core/src/lib/index.ts b/packages/workflow-core/src/lib/index.ts index 1b70da235f..dfa89f8cbc 100644 --- a/packages/workflow-core/src/lib/index.ts +++ b/packages/workflow-core/src/lib/index.ts @@ -50,5 +50,7 @@ export { HttpError } from './errors'; export { createWorkflow } from './create-workflow'; export { BUILT_IN_EVENT } from './built-in-event'; export type { BuiltInEvent } from './built-in-event'; +export { BUILT_IN_ACTION } from './built-in-action'; +export { type BuiltInAction } from './built-in-action'; export { ARRAY_MERGE_OPTION } from './utils/deep-merge-with-options'; export type { ArrayMergeOption } from './utils/deep-merge-with-options'; diff --git a/packages/workflow-core/src/lib/plugins/common-plugin/types.ts b/packages/workflow-core/src/lib/plugins/common-plugin/types.ts index a8ef64f463..3a12bb1b09 100644 --- a/packages/workflow-core/src/lib/plugins/common-plugin/types.ts +++ b/packages/workflow-core/src/lib/plugins/common-plugin/types.ts @@ -105,10 +105,13 @@ export interface WorkflowTokenPluginParams { expireInMinutes?: number; stateNames: string[]; action: (workflowTokenCallbackInput: WorkflowTokenCallbackInput) => Promise<{ - token: string; - customerName: string; - collectionFlowUrl: string; - customerNormalizedName: string; + collectionFlow: object; + metadata: { + token: string; + customerName: string; + collectionFlowUrl: string; + customerNormalizedName: string; + }; }>; successAction?: string; errorAction?: string; diff --git a/packages/workflow-core/src/lib/plugins/common-plugin/workflow-token-plugin.ts b/packages/workflow-core/src/lib/plugins/common-plugin/workflow-token-plugin.ts index 8a74aa345a..b03f609e6e 100644 --- a/packages/workflow-core/src/lib/plugins/common-plugin/workflow-token-plugin.ts +++ b/packages/workflow-core/src/lib/plugins/common-plugin/workflow-token-plugin.ts @@ -19,7 +19,7 @@ export class WorkflowTokenPlugin { this.action = pluginParams.action; this.successAction = pluginParams.successAction; this.errorAction = pluginParams.errorAction; - this.persistResponseDestination = 'metadata'; + this.persistResponseDestination = ''; } async invoke(context: TContext) { diff --git a/packages/workflow-core/src/lib/plugins/external-plugin/ballerine-email-plugin.ts b/packages/workflow-core/src/lib/plugins/external-plugin/ballerine-email-plugin.ts index 14612b8d76..a3bee24e56 100644 --- a/packages/workflow-core/src/lib/plugins/external-plugin/ballerine-email-plugin.ts +++ b/packages/workflow-core/src/lib/plugins/external-plugin/ballerine-email-plugin.ts @@ -65,6 +65,7 @@ export class BallerineEmailPlugin extends BallerineApiPlugin { ok: true, json: () => Promise.resolve({}), statusText: 'OK', + headers: {} as Headers, }; } diff --git a/packages/workflow-core/src/lib/plugins/external-plugin/email-plugin.ts b/packages/workflow-core/src/lib/plugins/external-plugin/email-plugin.ts index 4e06a5454c..a1d126fd50 100644 --- a/packages/workflow-core/src/lib/plugins/external-plugin/email-plugin.ts +++ b/packages/workflow-core/src/lib/plugins/external-plugin/email-plugin.ts @@ -57,6 +57,7 @@ export class EmailPlugin extends ApiPlugin { ok: true, json: () => Promise.resolve({}), statusText: 'OK', + headers: {} as Headers, }; } diff --git a/packages/workflow-core/src/lib/utils/definition-validator/states-validator.ts b/packages/workflow-core/src/lib/utils/definition-validator/states-validator.ts index d33266f5ed..e36a2b79fe 100644 --- a/packages/workflow-core/src/lib/utils/definition-validator/states-validator.ts +++ b/packages/workflow-core/src/lib/utils/definition-validator/states-validator.ts @@ -1,6 +1,7 @@ import { StateMachine } from 'xstate'; import { ruleValidator, TDefintionRules } from './rule-validator'; -import { AnyRecord } from '@ballerine/common'; +import { AnyRecord, isObject } from '@ballerine/common'; +import { BUILT_IN_EVENT } from '../../built-in-event'; type TTransitionEvent = string; @@ -8,6 +9,10 @@ type TTransitionOption = | { target: string; cond?: TDefintionRules; + actions?: string; + } + | { + actions: string; } | string; type TTransitionOptions = TTransitionOption[]; @@ -63,7 +68,26 @@ export const validateTransitionOnEvent = ({ currentState: string; transition: TTransitionOption; }) => { - const targetState = typeof transition === 'string' ? transition : transition.target; + const getTargetState = () => { + if (typeof transition === 'string') { + return transition; + } + + if (isObject(transition) && 'target' in transition) { + return transition.target; + } + + throw Error(`Unexpected transition object: ${JSON.stringify(transition)}`); + }; + const targetState = getTargetState(); + + if ( + isObject(transition) && + 'actions' in transition && + transition.actions === BUILT_IN_EVENT.NO_OP + ) { + return; + } if (!stateNames.includes(targetState)) { throw new Error(`Invalid transition from ${currentState} to ${targetState}`); diff --git a/packages/workflow-core/src/lib/workflow-runner.ts b/packages/workflow-core/src/lib/workflow-runner.ts index 7ed093d5e4..d63e3bdfae 100644 --- a/packages/workflow-core/src/lib/workflow-runner.ts +++ b/packages/workflow-core/src/lib/workflow-runner.ts @@ -5,6 +5,7 @@ import * as jsonLogic from 'json-logic-js'; import type { ActionFunction, MachineOptions, StateMachine } from 'xstate'; import { assign, createMachine, interpret } from 'xstate'; import { pluginsRegistry } from './constants'; +import { BUILT_IN_ACTION } from './built-in-action'; import { HttpError } from './errors'; import { BUILT_IN_EVENT } from './index'; import { logger } from './logger'; @@ -464,9 +465,17 @@ export class WorkflowRunner { } } + const state = this.#__currentState; + const noOp = () => { + logger.log(`${BUILT_IN_ACTION.NO_OP} action fired`, { + state, + }); + }; + const actions: MachineOptions['actions'] = { ...workflowActions, ...stateActions, + [BUILT_IN_ACTION.NO_OP]: noOp, }; const guards: MachineOptions['guards'] = { @@ -544,6 +553,7 @@ export class WorkflowRunner { return createMachine( { predictableActionArguments: true, + ...definition, on: { [BUILT_IN_EVENT.UPDATE_CONTEXT]: { actions: updateContext, @@ -551,8 +561,8 @@ export class WorkflowRunner { [BUILT_IN_EVENT.DEEP_MERGE_CONTEXT]: { actions: deepMergeContext, }, + ...definition.on, }, - ...definition, }, { actions, guards }, ); @@ -912,8 +922,12 @@ export class WorkflowRunner { mergeToContext( sourceContext: Record, informationToPersist: Record, - pathToPersist: string, + pathToPersist?: string, ) { + if (!pathToPersist) { + return this.deepMerge(informationToPersist, sourceContext); + } + const keys = pathToPersist.split('.') as Array; let obj = sourceContext; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4bd7bcc67..413accaf29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -73,22 +73,22 @@ importers: apps/backoffice-v2: dependencies: '@ballerine/blocks': - specifier: 0.2.28 + specifier: 0.2.29 version: link:../../packages/blocks '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../../packages/common '@ballerine/react-pdf-toolkit': - specifier: ^1.2.48 + specifier: ^1.2.50 version: link:../../packages/react-pdf-toolkit '@ballerine/ui': - specifier: ^0.5.48 + specifier: ^0.5.50 version: link:../../packages/ui '@ballerine/workflow-browser-sdk': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../sdks/workflow-browser-sdk '@ballerine/workflow-node-sdk': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../sdks/workflow-node-sdk '@botpress/webchat': specifier: ^2.1.10 @@ -359,10 +359,10 @@ importers: version: 3.22.4 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config-react': - specifier: ^2.0.26 + specifier: ^2.0.27 version: link:../../packages/eslint-config-react '@cspell/cspell-types': specifier: ^6.31.1 @@ -518,16 +518,16 @@ importers: apps/kyb-app: dependencies: '@ballerine/blocks': - specifier: 0.2.28 + specifier: 0.2.29 version: link:../../packages/blocks '@ballerine/common': - specifier: ^0.9.57 + specifier: ^0.9.58 version: link:../../packages/common '@ballerine/ui': - specifier: 0.5.49 + specifier: 0.5.50 version: link:../../packages/ui '@ballerine/workflow-browser-sdk': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../sdks/workflow-browser-sdk '@lukemorales/query-key-factory': specifier: ^1.0.3 @@ -660,10 +660,10 @@ importers: version: 3.23.4 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config-react': - specifier: ^2.0.26 + specifier: ^2.0.27 version: link:../../packages/eslint-config-react '@jest/globals': specifier: ^29.7.0 @@ -768,10 +768,10 @@ importers: apps/workflows-dashboard: dependencies: '@ballerine/common': - specifier: ^0.9.55 + specifier: ^0.9.58 version: link:../../packages/common '@ballerine/ui': - specifier: ^0.5.48 + specifier: ^0.5.50 version: link:../../packages/ui '@lukemorales/query-key-factory': specifier: ^1.0.3 @@ -907,10 +907,10 @@ importers: version: 3.22.4 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config-react': - specifier: ^2.0.26 + specifier: ^2.0.27 version: link:../../packages/eslint-config-react '@cspell/cspell-types': specifier: ^6.31.1 @@ -1000,10 +1000,10 @@ importers: examples/headless-example: dependencies: '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../../packages/common '@ballerine/workflow-browser-sdk': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../sdks/workflow-browser-sdk '@felte/reporter-svelte': specifier: ^1.1.5 @@ -1097,7 +1097,7 @@ importers: examples/report-generation-example: dependencies: '@ballerine/react-pdf-toolkit': - specifier: ^1.2.48 + specifier: ^1.2.50 version: link:../../packages/react-pdf-toolkit react: specifier: ^18.2.0 @@ -1140,7 +1140,7 @@ importers: packages/blocks: dependencies: '@ballerine/common': - specifier: ^0.9.55 + specifier: ^0.9.58 version: link:../common devDependencies: '@babel/core': @@ -1156,10 +1156,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../eslint-config '@rollup/plugin-babel': specifier: 5.3.1 @@ -1337,10 +1337,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -1489,7 +1489,7 @@ importers: packages/eslint-config-react: dependencies: '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../eslint-config eslint-plugin-react: specifier: ^7.33.2 @@ -1501,10 +1501,10 @@ importers: packages/react-pdf-toolkit: dependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/ui': - specifier: 0.5.49 + specifier: 0.5.50 version: link:../ui '@react-pdf/renderer': specifier: ^3.1.14 @@ -1623,10 +1623,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -1728,7 +1728,7 @@ importers: packages/ui: dependencies: '@ballerine/common': - specifier: ^0.9.55 + specifier: ^0.9.58 version: link:../common '@emotion/react': specifier: ^11.11.1 @@ -1840,10 +1840,10 @@ importers: version: 3.23.4 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/eslint-config-react': - specifier: ^2.0.26 + specifier: ^2.0.27 version: link:../eslint-config-react '@cspell/cspell-types': specifier: ^6.31.1 @@ -1951,7 +1951,7 @@ importers: packages/workflow-core: dependencies: '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../common ajv: specifier: ^8.12.0 @@ -1997,10 +1997,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -2141,7 +2141,7 @@ importers: sdks/web-ui-sdk: dependencies: '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../../packages/common '@zerodevx/svelte-toast': specifier: ^0.8.0 @@ -2268,10 +2268,10 @@ importers: sdks/workflow-browser-sdk: dependencies: '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../../packages/common '@ballerine/workflow-core': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../packages/workflow-core xstate: specifier: ^4.37.0 @@ -2287,10 +2287,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -2410,7 +2410,7 @@ importers: sdks/workflow-node-sdk: dependencies: '@ballerine/workflow-core': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../packages/workflow-core json-logic-js: specifier: ^2.0.2 @@ -2429,10 +2429,10 @@ importers: specifier: 7.16.7 version: 7.16.7(@babel/core@7.17.9) '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -2655,13 +2655,13 @@ importers: specifier: 3.347.1 version: 3.347.1 '@ballerine/common': - specifier: 0.9.57 + specifier: 0.9.58 version: link:../../packages/common '@ballerine/workflow-core': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../packages/workflow-core '@ballerine/workflow-node-sdk': - specifier: 0.6.75 + specifier: 0.6.77 version: link:../../sdks/workflow-node-sdk '@faker-js/faker': specifier: ^7.6.0 @@ -2839,10 +2839,10 @@ importers: version: 3.23.4 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/eslint-config '@cspell/cspell-types': specifier: ^6.31.1 @@ -3004,7 +3004,7 @@ importers: specifier: ^4.0.0 version: 4.0.0(astro@3.3.3)(tailwindcss@3.3.5)(ts-node@10.9.1) '@ballerine/common': - specifier: ^0.9.57 + specifier: ^0.9.58 version: link:../../packages/common astro: specifier: 3.3.3 @@ -3017,10 +3017,10 @@ importers: version: 0.14.5 devDependencies: '@ballerine/config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/config '@ballerine/eslint-config': - specifier: ^1.1.26 + specifier: ^1.1.27 version: link:../../packages/eslint-config eslint: specifier: ^8.46.0 @@ -25248,7 +25248,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.5) debug: 3.2.7 eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 @@ -25413,7 +25413,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.54.0)(typescript@4.9.5) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 diff --git a/sdks/web-ui-sdk/CHANGELOG.md b/sdks/web-ui-sdk/CHANGELOG.md index e24546d7b6..a9c09f33a4 100644 --- a/sdks/web-ui-sdk/CHANGELOG.md +++ b/sdks/web-ui-sdk/CHANGELOG.md @@ -1,5 +1,13 @@ # web-ui-sdk +## 1.5.59 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/common@0.9.58 + ## 1.5.58 ### Patch Changes diff --git a/sdks/web-ui-sdk/package.json b/sdks/web-ui-sdk/package.json index ee6cb9bee8..38e11d3052 100644 --- a/sdks/web-ui-sdk/package.json +++ b/sdks/web-ui-sdk/package.json @@ -21,7 +21,7 @@ "types": "dist/index.d.ts", "name": "@ballerine/web-ui-sdk", "private": false, - "version": "1.5.58", + "version": "1.5.59", "type": "module", "files": [ "dist" @@ -96,7 +96,7 @@ "vitest": "^0.24.5" }, "dependencies": { - "@ballerine/common": "0.9.57", + "@ballerine/common": "0.9.58", "@zerodevx/svelte-toast": "^0.8.0", "compressorjs": "^1.1.1", "deepmerge": "^4.3.0", diff --git a/sdks/workflow-browser-sdk/CHANGELOG.md b/sdks/workflow-browser-sdk/CHANGELOG.md index 777b50e446..98664fc202 100644 --- a/sdks/workflow-browser-sdk/CHANGELOG.md +++ b/sdks/workflow-browser-sdk/CHANGELOG.md @@ -1,5 +1,21 @@ # @ballerine/workflow-browser-sdk +## 0.6.77 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/workflow-core@0.6.77 + - @ballerine/common@0.9.58 + +## 0.6.76 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.76 + ## 0.6.75 ### Patch Changes diff --git a/sdks/workflow-browser-sdk/package.json b/sdks/workflow-browser-sdk/package.json index d41f858cc6..192eb83656 100644 --- a/sdks/workflow-browser-sdk/package.json +++ b/sdks/workflow-browser-sdk/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-browser-sdk", "author": "Ballerine ", - "version": "0.6.75", + "version": "0.6.77", "description": "workflow-browser-sdk", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -33,17 +33,17 @@ "node": ">=12" }, "dependencies": { - "@ballerine/common": "0.9.57", - "@ballerine/workflow-core": "0.6.75", + "@ballerine/common": "0.9.58", + "@ballerine/workflow-core": "0.6.77", "xstate": "^4.37.0" }, "devDependencies": { "@babel/core": "7.17.9", "@babel/preset-env": "7.16.11", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", + "@ballerine/config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/eslint-config": "^1.1.27", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-json": "^6.0.0", diff --git a/sdks/workflow-node-sdk/CHANGELOG.md b/sdks/workflow-node-sdk/CHANGELOG.md index e677c2aea3..6eb421c38c 100644 --- a/sdks/workflow-node-sdk/CHANGELOG.md +++ b/sdks/workflow-node-sdk/CHANGELOG.md @@ -1,5 +1,20 @@ # @ballerine/workflow-node-sdk +## 0.6.77 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/workflow-core@0.6.77 + +## 0.6.76 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.76 + ## 0.6.75 ### Patch Changes diff --git a/sdks/workflow-node-sdk/package.json b/sdks/workflow-node-sdk/package.json index 16e847112a..2eaaf6ef8c 100644 --- a/sdks/workflow-node-sdk/package.json +++ b/sdks/workflow-node-sdk/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflow-node-sdk", "author": "Ballerine ", - "version": "0.6.75", + "version": "0.6.77", "description": "workflow-node-sdk", "module": "./dist/esm/index.js", "main": "./dist/cjs/index.js", @@ -28,7 +28,7 @@ "node": ">=12" }, "dependencies": { - "@ballerine/workflow-core": "0.6.75", + "@ballerine/workflow-core": "0.6.77", "json-logic-js": "^2.0.2", "xstate": "^4.36.0" }, @@ -36,9 +36,9 @@ "@babel/core": "7.17.9", "@babel/preset-env": "7.16.11", "@babel/preset-typescript": "7.16.7", - "@ballerine/config": "^1.1.26", + "@ballerine/config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/eslint-config": "^1.1.27", "@rollup/plugin-babel": "5.3.1", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-json": "^6.0.0", diff --git a/services/websocket-service/CHANGELOG.md b/services/websocket-service/CHANGELOG.md index 1e9973f08f..ad77bb20ae 100644 --- a/services/websocket-service/CHANGELOG.md +++ b/services/websocket-service/CHANGELOG.md @@ -1,5 +1,11 @@ # @ballerine/websocket-service +## 0.1.27 + +### Patch Changes + +- Bump + ## 0.1.26 ### Patch Changes diff --git a/services/websocket-service/package.json b/services/websocket-service/package.json index 9e13691ef7..85e87b97b4 100644 --- a/services/websocket-service/package.json +++ b/services/websocket-service/package.json @@ -1,6 +1,6 @@ { "name": "@ballerine/websocket-service", - "version": "0.1.26", + "version": "0.1.27", "description": "websocket-service", "private": false, "scripts": { diff --git a/services/workflows-service/CHANGELOG.md b/services/workflows-service/CHANGELOG.md index 445d0fe705..46b74e9bb8 100644 --- a/services/workflows-service/CHANGELOG.md +++ b/services/workflows-service/CHANGELOG.md @@ -1,5 +1,23 @@ # @ballerine/workflows-service +## 0.7.81 + +### Patch Changes + +- Bump +- Updated dependencies + - @ballerine/workflow-core@0.6.77 + - @ballerine/common@0.9.58 + - @ballerine/workflow-node-sdk@0.6.77 + +## 0.7.80 + +### Patch Changes + +- Updated dependencies + - @ballerine/workflow-core@0.6.76 + - @ballerine/workflow-node-sdk@0.6.76 + ## 0.7.79 ### Patch Changes diff --git a/services/workflows-service/package.json b/services/workflows-service/package.json index 1e10671c55..ca48a9ebe8 100644 --- a/services/workflows-service/package.json +++ b/services/workflows-service/package.json @@ -1,7 +1,7 @@ { "name": "@ballerine/workflows-service", "private": false, - "version": "0.7.79", + "version": "0.7.81", "description": "workflow-service", "scripts": { "spellcheck": "cspell \"*\"", @@ -39,7 +39,7 @@ "upload-sourcemaps": "tsx scripts/upload-sourcemaps.ts", "prepare": "npm run prisma:generate", "db:data-migration:generate": "plop --plopfile ./prisma/data-migrations/plopfile.js --dest ./", - "db:data-migration:migrate": "node dist/src/data-migration/scripts/migrate", + "db:data-migration:migrate": "rimraf ./dist && npm run build && nest start --entryFile ./src/data-migration/scripts/migrate", "db:data-sync": "nest start --entryFile ./src/data-migration/scripts/sync/run", "db:data-migration:import": "tsx ./src/data-migration/scripts/import", "run-validation": "tsx ./scripts/run-validation.ts" @@ -47,12 +47,11 @@ "dependencies": { "@aws-sdk/client-s3": "3.347.1", "@aws-sdk/client-secrets-manager": "^3.620.1", - "@aws-sdk/client-secrets-manager": "^3.620.1", "@aws-sdk/lib-storage": "3.347.1", "@aws-sdk/s3-request-presigner": "3.347.1", - "@ballerine/common": "0.9.57", - "@ballerine/workflow-core": "0.6.75", - "@ballerine/workflow-node-sdk": "0.6.75", + "@ballerine/common": "0.9.58", + "@ballerine/workflow-core": "0.6.77", + "@ballerine/workflow-node-sdk": "0.6.77", "@faker-js/faker": "^7.6.0", "@nestjs/axios": "^2.0.0", "@nestjs/common": "^9.3.12", @@ -113,8 +112,8 @@ "zod": "^3.23.4" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config": "^1.1.27", "@cspell/cspell-types": "^6.31.1", "@nestjs/cli": "9.3.0", "@nestjs/swagger": "7.4.0", diff --git a/services/workflows-service/prisma/data-migrations b/services/workflows-service/prisma/data-migrations index 0b7e462361..1b5aefde3e 160000 --- a/services/workflows-service/prisma/data-migrations +++ b/services/workflows-service/prisma/data-migrations @@ -1 +1 @@ -Subproject commit 0b7e462361f048d0c3db72dc1309f421a09c94df +Subproject commit 1b5aefde3e6206f8050b9a7f4d0294a460bdb088 diff --git a/services/workflows-service/src/auth/workflow-token/workflow-token.service.ts b/services/workflows-service/src/auth/workflow-token/workflow-token.service.ts index bad936460e..e6c37a79a9 100644 --- a/services/workflows-service/src/auth/workflow-token/workflow-token.service.ts +++ b/services/workflows-service/src/auth/workflow-token/workflow-token.service.ts @@ -41,32 +41,43 @@ export class WorkflowTokenService { transaction, ); - const [uiDefinition, customer] = await Promise.all([ - this.uiDefinitionService.getByWorkflowDefinitionId( - workflowDefinitionId, - UiDefinitionContext.collection_flow, - [projectId], - ), - this.customerService.getByProjectId(projectId), - ]); - - const collectionFlow = buildCollectionFlowState({ - apiUrl: env.APP_API_URL, - steps: uiDefinition?.definition - ? getOrderedSteps( - (uiDefinition?.definition as Prisma.JsonObject)?.definition as Record< - string, - Record - >, - { finalStates: [...WORKFLOW_FINAL_STATES] }, - ).map(stepName => ({ - stateName: stepName, - })) - : [], - additionalInformation: { - customerCompany: customer.displayName, - }, - }); + let collectionFlow; + try { + const [uiDefinition, customer] = await Promise.all([ + this.uiDefinitionService.getByWorkflowDefinitionId( + workflowDefinitionId, + UiDefinitionContext.collection_flow, + [projectId], + ), + this.customerService.getByProjectId(projectId), + ]); + + collectionFlow = buildCollectionFlowState({ + apiUrl: env.APP_API_URL, + steps: uiDefinition?.definition + ? getOrderedSteps( + (uiDefinition?.definition as Prisma.JsonObject)?.definition as Record< + string, + Record + >, + { finalStates: [...WORKFLOW_FINAL_STATES] }, + ).map(stepName => ({ + stateName: stepName, + })) + : [], + additionalInformation: { + customerCompany: customer.displayName, + }, + }); + } catch (error) { + collectionFlow = buildCollectionFlowState({ + apiUrl: env.APP_API_URL, + steps: [], + additionalInformation: { + customerCompany: '', + }, + }); + } await this.workflowRuntimeDataRepository.updateStateById( workflowRuntimeDataId, diff --git a/services/workflows-service/src/filter/filter.controller.external.ts b/services/workflows-service/src/filter/filter.controller.external.ts index 9bb072bec6..0e48622646 100644 --- a/services/workflows-service/src/filter/filter.controller.external.ts +++ b/services/workflows-service/src/filter/filter.controller.external.ts @@ -90,7 +90,6 @@ export class FilterControllerExternal { } @common.Post() - @UseCustomerAuthGuard() @swagger.ApiCreatedResponse({ type: FilterModel }) @swagger.ApiForbiddenResponse() @UsePipes(new ZodValidationPipe(FilterCreateSchema, 'body')) diff --git a/services/workflows-service/src/ui-definition/ui-definition.controller.ts b/services/workflows-service/src/ui-definition/ui-definition.controller.ts index 7dfac9cf5e..08347f6d88 100644 --- a/services/workflows-service/src/ui-definition/ui-definition.controller.ts +++ b/services/workflows-service/src/ui-definition/ui-definition.controller.ts @@ -35,14 +35,21 @@ export class UIDefinitionController { name: 'id', schema: UIDefinitionWhereUniqueInputSchema, }, + { + type: 'body', + schema: Type.Object({ + name: Type.String(), + }), + }, ], response: Type.Any(), }) @common.Post(':id/copy') async copyUIDefinition( @common.Param('id') id: string, + @common.Body() body: { name: string }, @CurrentProject() currentProjectId: TProjectId, ) { - return this.uiDefinitionService.cloneUIDefinitionById(id, currentProjectId); + return this.uiDefinitionService.cloneUIDefinitionById(id, currentProjectId, body.name); } } diff --git a/services/workflows-service/src/ui-definition/ui-definition.repository.ts b/services/workflows-service/src/ui-definition/ui-definition.repository.ts index 57ef81f08e..167b6b189f 100644 --- a/services/workflows-service/src/ui-definition/ui-definition.repository.ts +++ b/services/workflows-service/src/ui-definition/ui-definition.repository.ts @@ -51,11 +51,11 @@ export class UiDefinitionRepository { ...args, where: { OR: [ + ...(args?.where ? [args.where] : []), { workflowDefinitionId, uiContext: uiContext, }, - ...(args?.where ? [args.where] : []), ], }, }, diff --git a/services/workflows-service/src/ui-definition/ui-definition.service.ts b/services/workflows-service/src/ui-definition/ui-definition.service.ts index 9f4426f7ae..46a3e62583 100644 --- a/services/workflows-service/src/ui-definition/ui-definition.service.ts +++ b/services/workflows-service/src/ui-definition/ui-definition.service.ts @@ -83,16 +83,22 @@ export class UiDefinitionService { ); } - async cloneUIDefinitionById(id: string, projectId: TProjectId) { + async cloneUIDefinitionById(id: string, projectId: TProjectId, newName: string) { const { createdAt, updatedAt, id: _, + crossEnvKey, + name, ...uiDefinition } = await this.repository.findById(id, {}, [projectId]); - //@ts-ignore - const uiDefinitionCopy = await this.create({ data: replaceNullsWithUndefined(uiDefinition) }); + const uiDefinitionCopy = await this.create({ + data: replaceNullsWithUndefined({ + ...uiDefinition, + name: newName, + }), + }); return uiDefinitionCopy; } diff --git a/services/workflows-service/src/workflow-defintion/workflow-definition.service.ts b/services/workflows-service/src/workflow-defintion/workflow-definition.service.ts index 5a01b35777..742f1e0102 100644 --- a/services/workflows-service/src/workflow-defintion/workflow-definition.service.ts +++ b/services/workflows-service/src/workflow-defintion/workflow-definition.service.ts @@ -111,6 +111,8 @@ export class WorkflowDefinitionService { merge(restArgs, { name, displayName, + projectId, + isPublic: false, version: 1, }), ) as Prisma.WorkflowDefinitionCreateArgs['data']; diff --git a/services/workflows-service/src/workflow/workflow.service.ts b/services/workflows-service/src/workflow/workflow.service.ts index 97dec21803..f4455f8687 100644 --- a/services/workflows-service/src/workflow/workflow.service.ts +++ b/services/workflows-service/src/workflow/workflow.service.ts @@ -1554,15 +1554,25 @@ export class WorkflowService { } const nowPlus30Days = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); - const workflowToken = await this.workflowTokenService.create( - currentProjectId, - { + let workflowToken; + try { + workflowToken = await this.workflowTokenService.create( + currentProjectId, + { + workflowRuntimeDataId: workflowRuntimeData.id, + endUserId: endUserId ?? null, + expiresAt: nowPlus30Days, + }, + transaction, + ); + } catch (error) { + this.logger.error('Failed to create workflow token', { + error, workflowRuntimeDataId: workflowRuntimeData.id, - endUserId: endUserId ?? null, - expiresAt: nowPlus30Days, - }, - transaction, - ); + endUserId, + }); + this.sentry.captureException(error as Error); + } const collectionFlow = buildCollectionFlowState({ apiUrl: env.APP_API_URL, @@ -1591,7 +1601,7 @@ export class WorkflowService { collectionFlow, metadata: { ...(workflowRuntimeData.context.metadata ?? {}), - token: workflowToken.token, + token: workflowToken?.token, collectionFlowUrl: env.COLLECTION_FLOW_URL, webUiSDKUrl: env.WEB_UI_SDK_URL, }, @@ -2099,6 +2109,24 @@ export class WorkflowService { transaction, ); + const collectionFlow = buildCollectionFlowState({ + apiUrl: env.APP_API_URL, + steps: uiDefinition?.definition + ? getOrderedSteps( + (uiDefinition?.definition as Prisma.JsonObject)?.definition as Record< + string, + Record + >, + { finalStates: [...WORKFLOW_FINAL_STATES] }, + ).map(stepName => ({ + stateName: stepName, + })) + : [], + additionalInformation: { + customerCompany: customer.displayName, + }, + }); + await this.workflowRuntimeDataRepository.updateById( workflowRuntimeId, { @@ -2110,10 +2138,13 @@ export class WorkflowService { ); return { - token: token, - customerName: customer.displayName, - collectionFlowUrl: env.COLLECTION_FLOW_URL!, - customerNormalizedName: customer.name, + collectionFlow, + metadata: { + token: token, + customerName: customer.displayName, + collectionFlowUrl: env.COLLECTION_FLOW_URL!, + customerNormalizedName: customer.name, + }, }; }, }); diff --git a/websites/docs/package.json b/websites/docs/package.json index ad9c17f937..2234d7aa81 100644 --- a/websites/docs/package.json +++ b/websites/docs/package.json @@ -17,14 +17,14 @@ "dependencies": { "@astrojs/starlight": "0.11.1", "@astrojs/tailwind": "^4.0.0", - "@ballerine/common": "^0.9.57", + "@ballerine/common": "^0.9.58", "astro": "3.3.3", "sharp": "^0.32.4", "shiki": "^0.14.3" }, "devDependencies": { - "@ballerine/config": "^1.1.26", - "@ballerine/eslint-config": "^1.1.26", + "@ballerine/config": "^1.1.27", + "@ballerine/eslint-config": "^1.1.27", "eslint": "^8.46.0", "eslint-config-prettier": "^9.0.0", "eslint-config-standard-with-typescript": "^37.0.0",