Skip to content

Commit

Permalink
feat: added collection flow utils & removed cf manager (#2810)
Browse files Browse the repository at this point in the history
* feat: added collection flow utils & removed cf manager

* feat: added get-ordered-steps util

* fix: added additional terminal state

* feat: refactor

* fix: type

* feat: common bump

* chore(package): update dependencies and add auto-commit script
- Add dotenv and openai to handle environment variables and generate commit messages
- Update @babel/core and related dependencies to version 7.25.2
- Introduce a new auto-commit script to streamline Git commits

(Your package.json has more updates than my dating history, and that’s saying something)

* chore(deps): update dependencies in pnpm-lock.yaml
- Clean up unnecessary duplicate entries for dotenv and openai
- Update @babel/core and other related packages from 7.25.2 to 7.23.7

(Your package management is like a modern art exhibit—nobody really understands it)

---------

Co-authored-by: Alon Peretz <[email protected]>
  • Loading branch information
chesterkmr and alonp99 authored Nov 4, 2024
1 parent 0717cb9 commit 0f588b7
Show file tree
Hide file tree
Showing 64 changed files with 1,017 additions and 827 deletions.
9 changes: 9 additions & 0 deletions apps/backoffice-v2/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# @ballerine/backoffice-v2

## 0.7.62

### Patch Changes

- Updated dependencies
- @ballerine/common@0.9.47
- @ballerine/workflow-browser-sdk@0.6.59
- @ballerine/workflow-node-sdk@0.6.59

## 0.7.61

### Patch Changes
Expand Down
8 changes: 4 additions & 4 deletions apps/backoffice-v2/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ballerine/backoffice-v2",
"version": "0.7.61",
"version": "0.7.62",
"description": "Ballerine - Backoffice",
"homepage": "https://github.com/ballerine-io/ballerine",
"repository": {
Expand Down Expand Up @@ -51,11 +51,11 @@
},
"dependencies": {
"@ballerine/blocks": "0.2.24",
"@ballerine/common": "0.9.46",
"@ballerine/common": "0.9.47",
"@ballerine/react-pdf-toolkit": "^1.2.40",
"@ballerine/ui": "^0.5.40",
"@ballerine/workflow-browser-sdk": "0.6.58",
"@ballerine/workflow-node-sdk": "0.6.58",
"@ballerine/workflow-browser-sdk": "0.6.59",
"@ballerine/workflow-node-sdk": "0.6.59",
"@botpress/webchat": "^2.1.10",
"@botpress/webchat-generator": "^0.2.9",
"@fontsource/inter": "^4.5.15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,21 @@ export class CollectionFlowProcessTracker implements IProcessTracker {
}

private getSteps() {
const steps = this.workflow?.context?.collectionFlow?.config?.steps;
const steps = this.workflow?.context?.collectionFlow?.state?.steps;

if (!steps?.length) return [];

// Create a map of stateName to orderNumber for efficient lookup
const stateOrderMap = new Map(steps.map(step => [step.stateName, step.orderNumber]));

// Get progress states and sort them by their corresponding orderNumber
return Object.keys(this.workflow?.context?.collectionFlow?.state?.progressBreakdown ?? {}).sort(
(a, b) => {
const orderA = stateOrderMap.get(a) ?? 0;
const orderB = stateOrderMap.get(b) ?? 0;

return orderA - orderB;
},
);
return steps.map(step => step.stepName);
}

private getCollectionFlowStatus(step: string) {
if (this.workflow?.context?.collectionFlow?.state?.progressBreakdown?.[step]?.isCompleted) {
const stepItem = this.workflow?.context?.collectionFlow?.state?.steps?.find(
s => s.stepName === step,
);

if (!stepItem) return processStatusToIcon[ProcessStatus.IDLE];

if (stepItem?.isCompleted) {
return processStatusToIcon[ProcessStatus.SUCCESS];
}

Expand Down
7 changes: 3 additions & 4 deletions apps/backoffice-v2/src/domains/workflows/fetchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { handleZodError } from '@/common/utils/handle-zod-error/handle-zod-error
import { WorkflowDefinitionByIdSchema } from '@/domains/workflow-definitions/fetchers';
import { AmlSchema } from '@/lib/blocks/components/AmlBlock/utils/aml-adapter';
import { ObjectWithIdSchema } from '@/lib/zod/utils/object-with-id/object-with-id';
import { CollectionFlowStatuses } from '@ballerine/common';
import { CollectionFlowStatusesEnum } from '@ballerine/common';
import qs from 'qs';
import { deepCamelKeys } from 'string-ts';
import { z } from 'zod';
Expand Down Expand Up @@ -120,12 +120,11 @@ export const BaseWorkflowByIdSchema = z.object({
.object({
config: z.object({
apiUrl: z.string().url(),
steps: z.array(z.object({ stateName: z.string(), orderNumber: z.number() })),
}),
state: z.object({
currentStep: z.string(),
status: z.enum(Object.values(CollectionFlowStatuses) as [string, ...string[]]),
progressBreakdown: z.record(z.string(), z.object({ isCompleted: z.boolean() })),
status: z.enum(Object.values(CollectionFlowStatusesEnum) as [string, ...string[]]),
steps: z.array(z.object({ stepName: z.string(), isCompleted: z.boolean() })),
}),
additionalInformation: z.record(z.string(), z.unknown()).optional(),
})
Expand Down
3 changes: 2 additions & 1 deletion apps/kyb-app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
### Patch Changes

- Updated dependencies
- @ballerine/ui@0.5.41
- @ballerine/common@0.9.47
- @ballerine/workflow-browser-sdk@0.6.59

## 0.3.72

Expand Down
6 changes: 3 additions & 3 deletions apps/kyb-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
},
"dependencies": {
"@ballerine/blocks": "0.2.24",
"@ballerine/ui": "0.5.41",
"@ballerine/common": "^0.9.46",
"@ballerine/workflow-browser-sdk": "0.6.58",
"@ballerine/ui": "0.5.40",
"@ballerine/common": "^0.9.47",
"@ballerine/workflow-browser-sdk": "0.6.59",
"@lukemorales/query-key-factory": "^1.0.3",
"@radix-ui/react-icons": "^1.3.0",
"@rjsf/core": "^5.9.0",
Expand Down
9 changes: 6 additions & 3 deletions apps/kyb-app/src/components/layouts/AppShell/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ export const Navigation = () => {
const { customer } = useCustomer();
const { exit, isExitAvailable } = useAppExit();

const currentPageNumber = payload?.collectionFlow?.config?.steps?.find(
step => step.stateName === currentPage?.stateName,
)?.orderNumber;
const currentPageNumber =
Number(
payload?.collectionFlow?.state?.steps?.findIndex(
step => step.stepName === currentPage?.stateName,
),
) + 1;

const isFirstStep = currentPageNumber === 1;
const isDisabled = state.isLoading;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export const selectDirectorsDocuments = (context: unknown): Document[] =>
export const usePageErrors = (context: CollectionFlowContext, pages: UIPage[]): PageError[] => {
return useMemo(() => {
const pagesWithErrors: PageError[] = pages.map(page => {
const pageNumber = context?.collectionFlow?.config?.steps?.find(
step => step.stateName === page.stateName,
)?.orderNumber;
const pageNumber = context?.collectionFlow?.state?.steps?.findIndex(
step => step.stepName === page.stateName,
);

const pageErrorBase: PageError = {
page: pageNumber ?? page.number,
page: pageNumber !== -1 ? Number(pageNumber) + 1 : page.number,
pageName: page.name,
stateName: page.stateName,
errors: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import { useUIElementState } from '@/components/organisms/UIRenderer/hooks/useUI
import { UIElementComponent } from '@/components/organisms/UIRenderer/types';
import { UIPage } from '@/domains/collection-flow';
import { useFlowTracking } from '@/hooks/useFlowTracking';
import { CollectionFlowManager, CollectionFlowStatuses } from '@ballerine/common';
import {
CollectionFlowStatusesEnum,
getCollectionFlowState,
setStepCompletionState,
} from '@ballerine/common';
import { Button } from '@ballerine/ui';
import { useCallback, useMemo } from 'react';

Expand Down Expand Up @@ -70,12 +74,19 @@ export const SubmitButton: UIElementComponent<{ text: string }> = ({ definition
const isFinishPage = currentPage?.name === pages.at(-1)?.name;

if (isFinishPage && isValid) {
const collectionFlowManager = new CollectionFlowManager(stateApi.getContext());
const context = stateApi.getContext();

const collectionFlow = getCollectionFlowState(context);

collectionFlowManager.state().status = CollectionFlowStatuses.completed;
collectionFlowManager.state().setStepCompletionState(currentPage?.stateName as string, true);
if (collectionFlow) {
collectionFlow.status = CollectionFlowStatusesEnum.completed;
setStepCompletionState(context, {
stepName: currentPage?.stateName as string,
completed: true,
});
}

stateApi.setContext(collectionFlowManager.context);
stateApi.setContext(context);
}

onClickHandler();
Expand Down
11 changes: 6 additions & 5 deletions apps/kyb-app/src/helpers/prepareInitialUIState.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { UIState } from '@/components/organisms/DynamicUI/hooks/useUIStateLogic/types';
import { UIPage } from '@/domains/collection-flow';
import { CollectionFlowContext } from '@/domains/collection-flow/types/flow-context.types';
import { CollectionFlowManager } from '@ballerine/common';
import { getCollectionFlowState } from '@ballerine/common';

export const isPageCompleted = (page: UIPage, context: CollectionFlowContext) => {
const flow = new CollectionFlowManager(context);

const result = flow.state().isStepCompleted(page.stateName!);
const collectionFlow = getCollectionFlowState(context);
const isStepCompleted = collectionFlow?.steps?.find(
step => step.stepName === page.stateName,
)?.isCompleted;

if (!page.stateName) return false;

return result;
return isStepCompleted;
};

export const prepareInitialUIState = (
Expand Down
56 changes: 34 additions & 22 deletions apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ import { Approved } from '@/pages/CollectionFlow/components/pages/Approved';
import { Failed } from '@/pages/CollectionFlow/components/pages/Failed';
import { Rejected } from '@/pages/CollectionFlow/components/pages/Rejected';
import { Success } from '@/pages/CollectionFlow/components/pages/Success';
import { CollectionFlowManager, CollectionFlowStatuses } from '@ballerine/common';
import {
CollectionFlowStatusesEnum,
getCollectionFlowState,
setCollectionFlowStatus,
setStepCompletionState,
} from '@ballerine/common';
import { AnyObject } from '@ballerine/ui';

const elems = {
Expand Down Expand Up @@ -74,20 +79,21 @@ export const CollectionFlow = withSessionProtected(() => {

const pageErrors = usePageErrors(context ?? ({} as CollectionFlowContext), elements || []);
const isRevision = useMemo(
() => context?.collectionFlow?.state?.status === CollectionFlowStatuses.revision,
() => getCollectionFlowState(context)?.status === CollectionFlowStatusesEnum.revision,
[context],
);

const initialContext: CollectionFlowContext = useMemo(() => {
const collectionFlowManager = new CollectionFlowManager(context as CollectionFlowContext);
const contextCopy = { ...context };
const collectionFlow = getCollectionFlowState(contextCopy);

if (isRevision) {
if (isRevision && collectionFlow) {
const revisionStateName = getRevisionStateName(pageErrors);
collectionFlowManager.state().currentStep =
revisionStateName || collectionFlowManager.state().currentStep;
collectionFlow.currentStep = revisionStateName || collectionFlow.currentStep;
revisionStateName || collectionFlow.currentStep;
}

return collectionFlowManager.context as CollectionFlowContext;
return contextCopy as CollectionFlowContext;
}, [isRevision, pageErrors]);

const initialUIState = useMemo(() => {
Expand All @@ -106,10 +112,10 @@ export const CollectionFlow = withSessionProtected(() => {
setLogoLoaded(false);
}, [customer?.logoImageUri]);

if (initialContext?.collectionFlow?.state?.status === CollectionFlowStatuses.approved)
if (getCollectionFlowState(initialContext)?.status === CollectionFlowStatusesEnum.approved)
return <Approved />;

if (initialContext?.collectionFlow?.state?.status === CollectionFlowStatuses.rejected)
if (getCollectionFlowState(initialContext)?.status === CollectionFlowStatusesEnum.rejected)
return <Rejected />;

return definition && context ? (
Expand All @@ -129,25 +135,31 @@ export const CollectionFlow = withSessionProtected(() => {
onNext={async (tools, prevState, currentState) => {
tools.setElementCompleted(prevState, true);

const collectionFlowManager = new CollectionFlowManager(stateApi.getContext());
const context = stateApi.getContext();

const isAnyStepCompleted = Object.values(
collectionFlowManager.state().progressBreakdown || {},
).some(step => step.isCompleted);
const collectionFlow = getCollectionFlowState(context);

collectionFlowManager.state().setStepCompletionState(prevState, true);
collectionFlowManager.state().currentStep = currentState;
if (collectionFlow) {
const steps = collectionFlow?.steps || [];

if (!isAnyStepCompleted) {
console.log('Collection flow touched, changing state to inprogress');
collectionFlowManager.state().status = CollectionFlowStatuses.inprogress;
const isAnyStepCompleted = steps.some(step => step.isCompleted);

console.log('Updating context to', collectionFlowManager.context);
}
setStepCompletionState(context, {
stepName: prevState,
completed: true,
});

collectionFlow.currentStep = currentState;

stateApi.setContext(collectionFlowManager.context);
if (!isAnyStepCompleted) {
console.log('Collection flow touched, changing state to inprogress');
setCollectionFlowStatus(context, CollectionFlowStatusesEnum.inprogress);
}

await stateApi.invokePlugin('sync_workflow_runtime');
stateApi.setContext(context);

await stateApi.invokePlugin('sync_workflow_runtime');
}
}}
>
{() => {
Expand Down
8 changes: 8 additions & 0 deletions examples/headless-example/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @ballerine/headless-example

## 0.3.58

### Patch Changes

- Updated dependencies
- @ballerine/common@0.9.47
- @ballerine/workflow-browser-sdk@0.6.59

## 0.3.57

### Patch Changes
Expand Down
6 changes: 3 additions & 3 deletions examples/headless-example/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@ballerine/headless-example",
"private": true,
"version": "0.3.57",
"version": "0.3.58",
"type": "module",
"scripts": {
"spellcheck": "cspell \"*\"",
Expand Down Expand Up @@ -34,8 +34,8 @@
"vite": "^4.5.3"
},
"dependencies": {
"@ballerine/common": "0.9.46",
"@ballerine/workflow-browser-sdk": "0.6.58",
"@ballerine/common": "0.9.47",
"@ballerine/workflow-browser-sdk": "0.6.59",
"@felte/reporter-svelte": "^1.1.5",
"@felte/validator-zod": "^1.0.13",
"@fontsource/inter": "^4.5.15",
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"workflow-builder:dev": "echo \"Error: no test specified\" && exit 1",
"web-ui:dev": "echo \"Error: no test specified\" && exit 1",
"commit": "git add . && git-cz",
"commit:auto": "git add . && node ./scripts/auto-commit.js",
"prepare": "husky install",
"changeset": "changeset",
"version-packages": "changeset version",
Expand All @@ -85,7 +86,9 @@
"lint-staged": "^11.2.6",
"ngrok": "5.0.0-beta.2",
"nx": "15.0.2",
"prettier": "^2.8.7"
"prettier": "^2.8.7",
"dotenv": "^16.4.5",
"openai": "^4.70.3"
},
"dependencies": {
"concurrently": "^7.6.0",
Expand Down
6 changes: 6 additions & 0 deletions packages/common/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @ballerine/common

## 0.9.47

### Patch Changes

- Refactored collection flow utils

## 0.9.46

### Patch Changes
Expand Down
3 changes: 2 additions & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": false,
"name": "@ballerine/common",
"author": "Ballerine <[email protected]>",
"version": "0.9.46",
"version": "0.9.47",
"description": "common",
"module": "./dist/esm/index.js",
"main": "./dist/cjs/index.js",
Expand Down Expand Up @@ -88,6 +88,7 @@
"json-schema-to-zod": "^0.6.3",
"lodash.get": "^4.4.2",
"lodash.isempty": "^4.4.0",
"xstate": "^5.18.2",
"zod": "^3.22.4"
}
}
Loading

0 comments on commit 0f588b7

Please sign in to comment.