From 2226e589b79a2f17d1f879da69158f68b45023ae Mon Sep 17 00:00:00 2001 From: Tomer Shvadron Date: Sun, 15 Sep 2024 17:45:10 +0300 Subject: [PATCH] Blocks data sorting (#2709) * feat: blocks data sorting * feat: pR comments fix --- .../lib/blocks/components/Details/Details.tsx | 24 +++++++++---- .../blocks/components/Details/interfaces.ts | 29 --------------- .../components/EditableDetails/interfaces.ts | 5 ++- .../ReadOnlyDetailsCell.tsx | 35 ++++++++++--------- .../lib/blocks/create-blocks-typed/types.ts | 7 +++- .../hooks/useAddressBlock/useAddressBlock.tsx | 5 +++ .../src/lib/blocks/utils/sort-data.ts | 22 ++++++++++++ 7 files changed, 71 insertions(+), 56 deletions(-) delete mode 100644 apps/backoffice-v2/src/lib/blocks/components/Details/interfaces.ts create mode 100644 apps/backoffice-v2/src/lib/blocks/utils/sort-data.ts diff --git a/apps/backoffice-v2/src/lib/blocks/components/Details/Details.tsx b/apps/backoffice-v2/src/lib/blocks/components/Details/Details.tsx index 7a27bc7936..77b7a34163 100644 --- a/apps/backoffice-v2/src/lib/blocks/components/Details/Details.tsx +++ b/apps/backoffice-v2/src/lib/blocks/components/Details/Details.tsx @@ -1,10 +1,11 @@ -import { FunctionComponent } from 'react'; -import { Separator } from '../../../../common/components/atoms/Separator/Separator'; -import { ctw } from '../../../../common/utils/ctw/ctw'; +import { Separator } from '@/common/components/atoms/Separator/Separator'; +import { ctw } from '@/common/utils/ctw/ctw'; import { EditableDetails } from '../EditableDetails/EditableDetails'; -import { IDetailsProps } from './interfaces'; +import { ExtractCellProps } from '@ballerine/blocks'; +import { FunctionComponent } from 'react'; +import { sortData } from '@/lib/blocks/utils/sort-data'; -export const Details: FunctionComponent = ({ +export const Details: FunctionComponent> = ({ id, value, hideSeparator, @@ -12,8 +13,17 @@ export const Details: FunctionComponent = ({ workflowId, documents = [], onSubmit, + props, }) => { - if (!value.data?.length) return null; + if (!value.data?.length) { + return null; + } + + const sortedData = sortData({ + data: value.data, + direction: props?.config?.sort?.direction, + predefinedOrder: props?.config?.sort?.predefinedOrder, + }); return (
= ({ valueId={value?.id} documents={documents} title={value?.title} - data={value?.data} + data={sortedData} contextUpdateMethod={contextUpdateMethod} onSubmit={onSubmit} /> diff --git a/apps/backoffice-v2/src/lib/blocks/components/Details/interfaces.ts b/apps/backoffice-v2/src/lib/blocks/components/Details/interfaces.ts deleted file mode 100644 index c8d8169d7b..0000000000 --- a/apps/backoffice-v2/src/lib/blocks/components/Details/interfaces.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { AnyObject } from '@ballerine/ui'; -import { IEditableDetailsDocument } from '@/lib/blocks/components/EditableDetails/interfaces'; - -export interface IDetailsProps { - id: string; - workflowId: string; - hideSeparator?: boolean; - documents?: IEditableDetailsDocument[]; - contextUpdateMethod?: 'base' | 'director'; - value: { - id: string; - title: string; - subtitle: string; - data: Array<{ - title: string; - isEditable: boolean; - type: string; - format?: string; - pattern?: string; - value: unknown; - dropdownOptions?: Array<{ label: string; value: string }>; - dependantOn?: string; - dependantValue?: string; - minimum?: string; - maximum?: string; - }>; - }; - onSubmit?: (document: AnyObject) => void; -} diff --git a/apps/backoffice-v2/src/lib/blocks/components/EditableDetails/interfaces.ts b/apps/backoffice-v2/src/lib/blocks/components/EditableDetails/interfaces.ts index ba4d4da5c3..c1c2cc0d23 100644 --- a/apps/backoffice-v2/src/lib/blocks/components/EditableDetails/interfaces.ts +++ b/apps/backoffice-v2/src/lib/blocks/components/EditableDetails/interfaces.ts @@ -18,14 +18,13 @@ export interface IEditableDetails { pattern?: string; maximum?: string; minimum?: string; - dropdownOptions?: Array; + dropdownOptions?: TDropdownOption[]; }>; valueId: string; id: string; - documents: Array; + documents: IEditableDetailsDocument[]; title: string; workflowId: string; contextUpdateMethod?: 'base' | 'director'; onSubmit?: (document: AnyObject) => void; - config: Record; } diff --git a/apps/backoffice-v2/src/lib/blocks/components/ReadOnlyDetailsCell/ReadOnlyDetailsCell.tsx b/apps/backoffice-v2/src/lib/blocks/components/ReadOnlyDetailsCell/ReadOnlyDetailsCell.tsx index c580440e64..e60eef6718 100644 --- a/apps/backoffice-v2/src/lib/blocks/components/ReadOnlyDetailsCell/ReadOnlyDetailsCell.tsx +++ b/apps/backoffice-v2/src/lib/blocks/components/ReadOnlyDetailsCell/ReadOnlyDetailsCell.tsx @@ -1,5 +1,5 @@ import { FunctionComponent } from 'react'; -import { ctw } from '../../../../common/utils/ctw/ctw'; +import { ctw } from '@/common/utils/ctw/ctw'; import { ExtractCellProps } from '@ballerine/blocks'; import { ReadOnlyDetail } from '@/common/components/atoms/ReadOnlyDetail/ReadOnlyDetail'; import { titleCase } from 'string-ts'; @@ -20,21 +20,24 @@ export const ReadOnlyDetailsCell: FunctionComponent - {value?.map(({ label, value }) => { - return ( -
- - {titleCase(label ?? '')} - - - {value} - -
- ); - })} + {value + ?.slice() + ?.sort((a, b) => a.label.localeCompare(b.label)) + .map(({ label, value }) => { + return ( +
+ + {titleCase(label ?? '')} + + + {value} + +
+ ); + })}
); }; diff --git a/apps/backoffice-v2/src/lib/blocks/create-blocks-typed/types.ts b/apps/backoffice-v2/src/lib/blocks/create-blocks-typed/types.ts index 5d61ab311a..28075eb23b 100644 --- a/apps/backoffice-v2/src/lib/blocks/create-blocks-typed/types.ts +++ b/apps/backoffice-v2/src/lib/blocks/create-blocks-typed/types.ts @@ -17,7 +17,7 @@ import { ICallToActionDocumentSelection } from '@/lib/blocks/components/Director import { IEditableDetailsDocument } from '@/lib/blocks/components/EditableDetails/interfaces'; import { TPDFViewerCell } from '@/lib/blocks/components/PDFViewerCell/interfaces'; import { Block } from '@ballerine/blocks'; -import { CommonWorkflowStates, GenericFunction } from '@ballerine/common'; +import { CommonWorkflowStates, GenericFunction, SortDirection } from '@ballerine/common'; import { AnyChildren, AnyObject, Image } from '@ballerine/ui'; import { ColumnDef, TableOptions } from '@tanstack/react-table'; import { ComponentProps, ReactNode } from 'react'; @@ -133,6 +133,11 @@ export type TDetailsCell = { maximum?: string; }>; }; + props?: { + config?: { + sort?: { direction?: SortDirection; predefinedOrder?: string[] }; + }; + }; onSubmit?: (document: AnyObject) => void; }; diff --git a/apps/backoffice-v2/src/lib/blocks/hooks/useAddressBlock/useAddressBlock.tsx b/apps/backoffice-v2/src/lib/blocks/hooks/useAddressBlock/useAddressBlock.tsx index 6a4f008572..8f2544cbbb 100644 --- a/apps/backoffice-v2/src/lib/blocks/hooks/useAddressBlock/useAddressBlock.tsx +++ b/apps/backoffice-v2/src/lib/blocks/hooks/useAddressBlock/useAddressBlock.tsx @@ -59,6 +59,11 @@ export const useAddressBlock = ({ isEditable: false, })), }, + props: { + config: { + sort: { predefinedOrder: ['street', 'streetNumber', 'city', 'country'] }, + }, + }, workflowId: workflow?.id, documents: workflow?.context?.documents, }) diff --git a/apps/backoffice-v2/src/lib/blocks/utils/sort-data.ts b/apps/backoffice-v2/src/lib/blocks/utils/sort-data.ts new file mode 100644 index 0000000000..928bd2dd0b --- /dev/null +++ b/apps/backoffice-v2/src/lib/blocks/utils/sort-data.ts @@ -0,0 +1,22 @@ +import { SortDirection } from '@ballerine/common'; +import { ExtractCellProps } from '@ballerine/blocks'; + +export const sortData = ({ + data, + direction = 'asc', + predefinedOrder = [], +}: { + direction?: SortDirection; + predefinedOrder?: string[]; + data: ExtractCellProps<'details'>['value']['data']; +}) => { + const orderedData = predefinedOrder.map(key => data.find(value => value.title === key)); + + const restData = data + .filter(data => !predefinedOrder.includes(data.title)) + .sort((a, b) => + direction === 'asc' ? a.title.localeCompare(b.title) : b.title.localeCompare(a.title), + ); + + return [...orderedData, ...restData].filter(Boolean); +};