Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
balzdur committed Jul 10, 2023
1 parent a6d55d4 commit 02e0b85
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 69 deletions.
67 changes: 16 additions & 51 deletions apps/builder/app/components/Edit/EditAstNode.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEditorIdentifiers } from '@marble-front/builder/services/editor/identifiers';
import { type AstNode, NewAstNode } from '@marble-front/models';
import { Combobox, Select } from '@marble-front/ui/design-system';
import { forwardRef, useState } from 'react';
import { forwardRef, useCallback, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import { useGetOperatorLabel } from '../Scenario/Formula/Operators';
Expand Down Expand Up @@ -56,9 +57,10 @@ const EditOperand = forwardRef<
onChange: (value: AstNode | null) => void;
}
>(({ value, onChange, ...otherProps }, ref) => {
const getIdentifierOptions = useGetIdentifierOptions();
const [inputValue, setInputValue] = useState('');
const [selectedItem, setSelectedItem] = useState<
(typeof mockedIdentifiers)[number] | null
ReturnType<typeof getIdentifierOptions>[number] | null
>(null);
const items = getIdentifierOptions(inputValue);

Expand All @@ -73,7 +75,7 @@ const EditOperand = forwardRef<
}}
nullable
>
<div className="relative max-w-xs">
<div className="relative">
<Combobox.Input
ref={ref}
displayValue={(item?: (typeof items)[number]) => item?.label ?? ''}
Expand All @@ -82,15 +84,14 @@ const EditOperand = forwardRef<
otherProps?.onBlur?.();
}}
/>
<Combobox.Options className="w-full">
<Combobox.Options className="w-fit">
{filteredItems.map((item) => (
<Combobox.Option
key={item.label}
value={item}
className="flex flex-col gap-1"
>
<span>{item.label}</span>
<span className="text-sm text-gray-700">{item.node.name}</span>
</Combobox.Option>
))}
</Combobox.Options>
Expand All @@ -100,49 +101,6 @@ const EditOperand = forwardRef<
});
EditOperand.displayName = 'EditOperand';

const mockedIdentifiers: { label: string; node: AstNode }[] = [
{
label: 'account.is_frozen',
node: NewAstNode({
name: 'DB_FIELD_BOOL',
namedChildren: {
triggerTableName: {
name: 'STRING_CONSTANT',
constant: 'transaction',
children: [],
namedChildren: {},
},
path: {
name: 'STRING_LIST_CONSTANT',
constant: ['account'],
children: [],
namedChildren: {},
},
fieldName: {
name: 'STRING_CONSTANT',
constant: 'is_frozen',
children: [],
namedChildren: {},
},
},
}),
},
{
label: 'amount',
node: NewAstNode({
name: 'PAYLOAD_FIELD_FLOAT',
namedChildren: {
fieldName: {
name: 'STRING_CONSTANT',
constant: 'amount',
children: [],
namedChildren: {},
},
},
}),
},
];

function coerceToConstant(search: string) {
const parsedNumber = Number(search);
const isNumber = !isNaN(parsedNumber);
Expand All @@ -166,9 +124,16 @@ function coerceToConstant(search: string) {
};
}

function getIdentifierOptions(search: string) {
if (!search) return mockedIdentifiers;
return [...mockedIdentifiers, coerceToConstant(search)];
function useGetIdentifierOptions() {
const identifiers = useEditorIdentifiers();

return useCallback(
(search: string) => {
if (!search) return identifiers;
return [...identifiers, coerceToConstant(search)];
},
[identifiers]
);
}

const EditOperator = forwardRef<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import {
} from '@marble-front/builder/components/Edit';
import { Consequence } from '@marble-front/builder/components/Scenario/Rule/Consequence';
import { authenticator } from '@marble-front/builder/services/auth/auth.server';
import { EditorIdentifiersProvider } from '@marble-front/builder/services/editor/identifiers';
import { getServerEnv } from '@marble-front/builder/utils/environment.server';
import { fromParams, fromUUID } from '@marble-front/builder/utils/short-uuid';
import { getScenarioIterationRule } from '@marble-front/repositories';
import { editor, getScenarioIterationRule } from '@marble-front/repositories';
import { Button, Tag } from '@marble-front/ui/design-system';
import { json, type LoaderArgs } from '@remix-run/node';
import { Link, useLoaderData } from '@remix-run/react';
Expand All @@ -32,23 +33,33 @@ export async function loader({ request, params }: LoaderArgs) {
});

const ruleId = fromParams(params, 'ruleId');
const scenarioId = fromParams(params, 'scenarioId');

const scenarioIterationRule = await getScenarioIterationRule({
const scenarioIterationRule = getScenarioIterationRule({
ruleId,
tokenService,
baseUrl: getServerEnv('MARBLE_API_DOMAIN'),
});

return json(scenarioIterationRule);
const identifiers = editor.listIdentifiers({
scenarioId,
tokenService,
baseUrl: getServerEnv('MARBLE_API_DOMAIN'),
});

return json({
rule: await scenarioIterationRule,
identifiers: await identifiers,
});
}

export default function RuleView() {
const rule = useLoaderData<typeof loader>();
const { rule, identifiers } = useLoaderData<typeof loader>();

const formMethods = useForm({
// defaultValues: {
// astNode: rule.astNode as RootAstNode<any, any>,
// },
defaultValues: {
astNode: rule.astNode,
},
});

return (
Expand All @@ -69,14 +80,16 @@ export default function RuleView() {
<div className="max-w flex flex-col gap-4">
<Consequence scoreIncrease={rule.scoreModifier} />
<Paper.Container scrollable={false}>
<FormProvider {...formMethods}>
{/* <RootOrOperator
renderAstNode={({ name }) => <WildEditAstNode name={name} />}
/> */}
<RootOrOperator
renderAstNode={({ name }) => <EditAstNode name={name} />}
/>
</FormProvider>
<EditorIdentifiersProvider identifiers={identifiers}>
<FormProvider {...formMethods}>
{/* <RootOrOperator
renderAstNode={({ name }) => <WildEditAstNode name={name} />}
/> */}
<RootOrOperator
renderAstNode={({ name }) => <EditAstNode name={name} />}
/>
</FormProvider>
</EditorIdentifiersProvider>
</Paper.Container>
<Button
onClick={formMethods.handleSubmit(
Expand Down Expand Up @@ -115,7 +128,9 @@ export default function RuleView() {
<DevTool
control={formMethods.control}
placement="bottom-right"
// styles={{ panel: { width: '1000px' } }}
styles={{
panel: { width: '1000px' },
}}
/>
)}
</ClientOnly>
Expand Down
42 changes: 42 additions & 0 deletions apps/builder/app/services/editor/identifiers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createSimpleContext } from '@marble-front/builder/utils/create-context';
import { type AstNode } from '@marble-front/models';

function getIdentifierDisplayName(identifiers: AstNode) {
switch (identifiers.name) {
case 'DatabaseAccess':
const { path, fieldName } = identifiers.namedChildren;
return [...path.constant, fieldName.constant].join('.');
default:
return undefined;
}
}

const EditorIdentifiersContext =
createSimpleContext<{ label: string; node: AstNode }[]>('EditorIdentifiers');

export function EditorIdentifiersProvider({
children,
identifiers,
}: {
children: React.ReactNode;
identifiers: {
dataAccessors: AstNode[];
};
}) {
const value = identifiers.dataAccessors
.map((dataAccessor) => ({
label: getIdentifierDisplayName(dataAccessor),
node: dataAccessor,
}))
.filter(
(identifier): identifier is { label: string; node: AstNode } =>
identifier.label !== undefined
);
return (
<EditorIdentifiersContext.Provider value={value}>
{children}
</EditorIdentifiersContext.Provider>
);
}

export const useEditorIdentifiers = EditorIdentifiersContext.useValue;
Empty file.
15 changes: 14 additions & 1 deletion libs/models/src/lib/ast-expression.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { type ScenarioIterationRule } from '@marble-front/api/marble';
import {
type NodeDto,
type ScenarioIterationRule,
} from '@marble-front/api/marble';
import { assertNever } from '@marble-front/typescript-utils';
import * as R from 'remeda';

import {
isConstantOperator,
Expand Down Expand Up @@ -111,3 +115,12 @@ export function adaptFormulaDto(

assertNever('unknwon Operator:', formula);
}

export function adaptNodeDto(nodeDto: NodeDto): AstNode {
return NewAstNode({
name: nodeDto.name,
constant: nodeDto.constant,
children: nodeDto.children?.map(adaptNodeDto),
namedChildren: R.mapValues(nodeDto.named_children ?? {}, adaptNodeDto),
});
}
2 changes: 1 addition & 1 deletion libs/repositories/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './lib/repositories';
export * from './lib';
30 changes: 30 additions & 0 deletions libs/repositories/src/lib/editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
getMarbleAPIClient,
type TokenService,
} from '@marble-front/api/marble';
import { adaptNodeDto } from '@marble-front/models';

async function listIdentifiers({
scenarioId,
tokenService,
baseUrl,
}: {
scenarioId: string;
tokenService: TokenService<string>;
baseUrl: string;
}) {
const marbleApiClient = getMarbleAPIClient({
tokenService,
baseUrl,
});

const { data_accessors } = await marbleApiClient.listIdentifiers(scenarioId);

const dataAccessors = data_accessors.map(adaptNodeDto);

return { dataAccessors };
}

export const editor = {
listIdentifiers,
};
1 change: 1 addition & 0 deletions libs/repositories/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './editor';
export * from './repositories';

0 comments on commit 02e0b85

Please sign in to comment.