Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(filters): implement create filter functionality #2881

Merged
merged 8 commits into from
Dec 11, 2024
46 changes: 35 additions & 11 deletions apps/kyb-app/src/pages/CollectionFlow/CollectionFlow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,19 +246,43 @@ export const CollectionFlow = withSessionProtected(() => {
<AppShell.Content>
<AppShell.FormContainer>
{localStorage.getItem('devmode') ? (
<div className="flex flex-col gap-4">
DEBUG
<div>
{currentPage
? currentPage.stateName
: 'Page not found and state ' + state}
<div className="mb-6 rounded-lg border border-amber-200 bg-amber-50 p-4">
<div className="mb-4 flex items-center gap-2">
<div className="h-2 w-2 animate-pulse rounded-full bg-amber-500" />
<span
className="cursor-help font-medium text-amber-900 hover:underline"
data-tooltip-id="debug-mode-tooltip"
data-tooltip-content="In debug mode you can navigate between steps without validation. Be aware that if required data is missing, plugins may fail when processing data at the end of the flow."
>
Debug Mode Active
</span>
</div>
<div className="flex gap-4">
<button onClick={() => stateApi.sendEvent('PREVIOUS')}>
prev

<div className="mb-3 text-sm text-amber-800">
Current State:{' '}
{currentPage ? (
<span className="font-medium">
{currentPage.stateName}
</span>
) : (
<span className="italic">
Page not found - state: {state}
</span>
)}
</div>

<div className="flex gap-3">
<button
onClick={() => stateApi.sendEvent('PREVIOUS')}
className="rounded bg-amber-100 px-3 py-1.5 text-sm font-medium text-amber-900 transition-colors hover:bg-amber-200"
>
Previous
</button>
<button onClick={() => stateApi.sendEvent('NEXT')}>
next
<button
onClick={() => stateApi.sendEvent('NEXT')}
className="rounded bg-amber-100 px-3 py-1.5 text-sm font-medium text-amber-900 transition-colors hover:bg-amber-200"
>
Next
</button>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,54 @@ 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';

export const defaultColumns: WorkflowTableColumnDef<IWorkflow>[] = [
export const defaultColumns: Array<WorkflowTableColumnDef<IWorkflow>> = [
{
accessorKey: 'id',
cell: info => info.getValue<string>(),
header: () => 'ID',
cell: info => (
<div className="flex items-center gap-2">
<span className="font-mono text-sm text-gray-600">{info.getValue<string>()}</span>
<button
onClick={() => navigator.clipboard.writeText(info.getValue<string>())}
className="text-gray-400 hover:text-gray-600"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
),
alonp99 marked this conversation as resolved.
Show resolved Hide resolved
header: () => <span className="font-semibold">ID</span>,
},
{
accessorKey: 'workflowDefinitionName',
cell: info => info.getValue<string>(),
cell: info => <span className="font-medium text-blue-600">{info.getValue<string>()}</span>,
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Workflow Definition Name" />
),
},
{
accessorKey: 'workflowDefinitionId',
cell: info => <CloneWorkflowDefinitionButton workflowDefinitionId={info.getValue<string>()} />,
header: '',
header: () => '',
},
{
accessorKey: 'status',
cell: info => (
<div className="font-inter flex flex-row flex-nowrap gap-4 font-medium capitalize">
<div className="flex items-center gap-4">
<HealthIndicator healthStatus={getWorkflowHealthStatus(info.row.original)} />
{info.getValue<string>() || ''}
<span className="font-medium capitalize">{info.getValue<string>() || ''}</span>
</div>
),
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
Expand All @@ -50,34 +73,47 @@ export const defaultColumns: WorkflowTableColumnDef<IWorkflow>[] = [
{
accessorKey: 'assignee',
accessorFn: row => (row.assignee ? `${row.assignee.firstName} ${row.assignee.lastName}` : '-'),
cell: info => info.getValue<string>(),
cell: info => <span className="text-gray-700">{info.getValue<string>()}</span>,
header: ({ column }) => <DataTableColumnHeader column={column} title="Assign To" />,
},
{
accessorKey: 'context',
accessorFn: row => JSON.stringify(row.context),
cell: info => <JSONViewButton json={info.getValue<string>()} />,
header: () => 'Context',
cell: info => (
<div className="flex flex-row items-center gap-3">
<JSONViewButton
trigger={
<Eye className="h-5 w-5 cursor-pointer text-gray-600 transition-colors hover:text-blue-600" />
}
json={info.getValue<string>()}
/>
</div>
),
alonp99 marked this conversation as resolved.
Show resolved Hide resolved
header: () => <span className="font-semibold">Context</span>,
},
{
accessorKey: 'view-workflow',
accessorFn: row => row.id,
cell: () => '-',
header: () => 'Workflow',
header: () => <span className="font-semibold">Workflow</span>,
},
{
accessorKey: 'resolvedAt',
cell: info => (info.getValue<Date>() ? formatDate(info.getValue<Date>()) : '-'),
cell: info => (
<span className="text-gray-700">
{info.getValue<Date>() ? formatDate(info.getValue<Date>()) : '-'}
</span>
),
header: ({ column }) => <DataTableColumnHeader column={column} title="Resolved At" />,
},
{
accessorKey: 'createdBy',
cell: info => info.getValue<string>(),
cell: info => <span className="text-gray-700">{info.getValue<string>()}</span>,
header: ({ column }) => <DataTableColumnHeader column={column} title="Created By" />,
},
{
accessorKey: 'createdAt',
cell: info => formatDate(info.getValue<Date>()),
cell: info => <span className="text-gray-700">{formatDate(info.getValue<Date>())}</span>,
header: ({ column }) => <DataTableColumnHeader column={column} title="Created At" />,
},
];
12 changes: 11 additions & 1 deletion apps/workflows-dashboard/src/domains/filters/filters.api.ts
Original file line number Diff line number Diff line change
@@ -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) => {
Expand All @@ -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;
};
17 changes: 17 additions & 0 deletions apps/workflows-dashboard/src/domains/filters/filters.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface IFilter {
entity: string;
query: object;
createdAt: string;
projectId: string;
}

export interface GetFiltersListDto {
Expand All @@ -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;
};
alonp99 marked this conversation as resolved.
Show resolved Hide resolved
projectId: string;
}
8 changes: 6 additions & 2 deletions apps/workflows-dashboard/src/domains/filters/query-keys.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
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', {
list: (query: GetFiltersListDto) => ({
queryKey: [{ query }],
queryFn: () => fetchFiltersList(query),
}),
create: () => ({
queryKey: ['create'],
queryFn: (dto: CreateFilterDto) => createFilter(dto),
}),
});
Original file line number Diff line number Diff line change
Expand Up @@ -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;
alonp99 marked this conversation as resolved.
Show resolved Hide resolved
};

export const fetchUIDefinition = async (dto: GetUIDefinitionByIdDto) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface IUIDefinition {
uiSchema: IUISchema;
locales?: object;
createdAt: string;
name: string;
theme?: object;
}

export interface UpdateUIDefinitionDto {
Expand All @@ -23,6 +25,7 @@ export interface UpdateUIDefinitionDto {

export interface CopyUIDefinitionDto {
uiDefinitionId: string;
name: string;
}
export interface GetUIDefinitionByIdDto {
uiDefinitionId: string;
Expand Down
Loading
Loading