Skip to content

Add WFO Object and Array field #1980

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wicked-grapes-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@orchestrator-ui/orchestrator-ui-components': patch
---

WfoArrayField, WfoObjectField, fix some import and types for the forms
838 changes: 805 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/orchestrator-ui-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"next-query-params": "^5.0.0",
"object-hash": "^3.0.0",
"prism-themes": "^1.9.0",
"pydantic-forms": "^0.3.1",
"pydantic-forms": "^0.4.0",
"react-diff-view": "^3.2.0",
"react-draggable": "^4.4.6",
"react-redux": "^9.1.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { EuiCheckbox, EuiFlexItem, EuiText } from '@elastic/eui';

import { useWithOrchestratorTheme } from '@/hooks';

import { getStyles } from './AcceptFieldStyling';
import { getAcceptFieldStyles } from './AcceptFieldStyling';
import { FieldProps } from './types';

type AcceptItemType =
Expand Down Expand Up @@ -73,7 +73,7 @@ function Accept({
...props
}: AcceptFieldProps) {
const t = useTranslations();
const { acceptFieldStyle } = useWithOrchestratorTheme(getStyles);
const { acceptFieldStyle } = useWithOrchestratorTheme(getAcceptFieldStyles);

const legacy = !data;
const i18nBaseKey = data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css } from '@emotion/react';

import { WfoTheme } from '@/hooks';

export const getStyles = ({ theme }: WfoTheme) => {
export const getAcceptFieldStyles = ({ theme }: WfoTheme) => {
const acceptFieldStyle = css({
'.acceptField': {
'label.warning': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiCheckbox, EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui';

import { FieldProps } from '@/components';
import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { useWithOrchestratorTheme } from '@/hooks';
import { FieldProps } from '@/types';

import { boolFieldStyling } from './BoolFieldStyling';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { connectField } from 'uniforms';

import { EuiHorizontalRule } from '@elastic/eui';

import { FieldProps } from '@/types';
import { FieldProps } from '@/components';

export type DividerFieldProps = FieldProps<null, object, null, HTMLDivElement>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import React from 'react';

import { connectField, filterDOMProps } from 'uniforms';

import { FieldProps } from '@/types';
import { FieldProps } from '@/components';

export type ErrorFieldProps = FieldProps<null>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import React from 'react';

import { connectField, filterDOMProps } from 'uniforms';

import { FieldProps } from '@/components';
import { useOrchestratorTheme } from '@/hooks';
import { FieldProps } from '@/types';

export type LabelFieldProps = FieldProps<null, object, null, HTMLDivElement>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiFormRow, EuiText, EuiTextArea } from '@elastic/eui';

import { FieldProps } from '@/types';
import { FieldProps } from '@/components';

export type LongTextFieldProps = FieldProps<
string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiFieldNumber, EuiFormRow, EuiText } from '@elastic/eui';

import { FieldProps } from '@/components';
import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { useWithOrchestratorTheme } from '@/hooks';
import { getFormFieldsBaseStyle } from '@/theme';
import { FieldProps } from '@/types';

export type NumFieldProps = FieldProps<
number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiFormRow, EuiRadio, EuiText } from '@elastic/eui';

import { FieldProps } from '@/types';
import { FieldProps } from '@/components';

const base64 =
typeof btoa !== 'undefined'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import React from 'react';

import { filterDOMProps, useForm } from 'uniforms';

import { FieldProps } from '@/types';
import { FieldProps } from '@/components';

export type SubmitFieldProps = FieldProps<
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiFieldText, EuiFormRow, EuiText } from '@elastic/eui';

import { FieldProps } from '@/components';
import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { useWithOrchestratorTheme } from '@/hooks';
import { getFormFieldsBaseStyle } from '@/theme';
import { FieldProps } from '@/types';

export type TextFieldProps = FieldProps<string>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useWithOrchestratorTheme } from '@/hooks';

import { ContactPerson } from '../types';
import { isEmpty } from '../utils';
import { getStyles } from './ContactPersonAutocompleteStyles';
import { getContactPersonStyles } from './ContactPersonAutocompleteStyles';

interface ContactPersonAutocompleteProps {
query: string;
Expand All @@ -39,8 +39,9 @@ export const ContactPersonAutocomplete = ({
itemSelected,
suggestions,
}: ContactPersonAutocompleteProps) => {
const { contactPersonAutocompleteStyling } =
useWithOrchestratorTheme(getStyles);
const { contactPersonAutocompleteStyling } = useWithOrchestratorTheme(
getContactPersonStyles,
);

// Intentionally not done with state since we don't need a rerender
// This is only to store a ref for the scroll into view part
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css } from '@emotion/react';

import { WfoTheme } from '@/hooks';

export const getStyles = ({ theme }: WfoTheme) => {
export const getContactPersonStyles = ({ theme }: WfoTheme) => {
const contactPersonAutocompleteStyling = css`
.autocomplete-container {
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import { connectField, filterDOMProps } from 'uniforms';

import { EuiFilePicker, EuiFormRow, EuiText } from '@elastic/eui';

import { FieldProps } from '@/components';
import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { useOrchestratorTheme, useWithOrchestratorTheme } from '@/hooks';
import { useUploadFileMutation } from '@/rtk/endpoints/fileUpload';
import { FieldProps } from '@/types';

export type FileUploadProps = FieldProps<string>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ export * from './CustomerField';
export * from './ConnectedSelectField';
export * from './deprecated/FileUploadField';
export * from './commonStyles';
export * from './types';
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type FieldProps<
export interface ContactPerson {
name: string;
email: string;
phone?: string;
}

export interface Option<Value = string> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { RowRenderComponent } from 'pydantic-forms';

import { EuiFormRow, EuiText } from '@elastic/eui';

import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { getCommonFormFieldStyles } from '@/components';
import { useWithOrchestratorTheme } from '@/hooks';

export const Row: RowRenderComponent = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,24 @@ import {
zodValidationPresets,
} from 'pydantic-forms';

import { FetchBaseQueryError } from '@reduxjs/toolkit/query';

import { PATH_TASKS, PATH_WORKFLOWS, WfoLoading } from '@/components';
import { StartWorkflowPayload } from '@/pages/processes/WfoStartProcessPage';
import { HttpStatus } from '@/rtk';
import { HttpStatus, isFetchBaseQueryError, isRecord } from '@/rtk';
import { useStartProcessMutation } from '@/rtk/endpoints/forms';
import { useAppSelector } from '@/rtk/hooks';
import { FormValidationError } from '@/types';

import { Footer } from './Footer';
import { Row } from './Row';
import { Checkbox, Divider, Label, Summary, Text, TextArea } from './fields';
import {
Checkbox,
Divider,
Label,
Summary,
Text,
TextArea,
WfoArrayField,
WfoObjectField,
} from './fields';

interface WfoPydanticFormProps {
processName: string;
Expand All @@ -46,7 +52,7 @@ export const WfoPydanticForm = ({
const [startProcess] = useStartProcessMutation();
const router = useRouter();
const t = useTranslations('pydanticForms.userInputForm');
const componentMatcher = useAppSelector(
const componentMatcherExtender = useAppSelector(
(state) => state.pydanticForm?.componentMatcher,
);

Expand Down Expand Up @@ -81,40 +87,26 @@ export const WfoPydanticForm = ({
userInputs: [{ ...startProcessPayload }, ...requestBody],
});
return response
.then((result) => {
return new Promise<Record<string, object | string>>(
(resolve) => {
if (result.error) {
const error =
result.error as FetchBaseQueryError;
if (
error.status === HttpStatus.FormNotComplete
) {
const data = error.data as Record<
string,
object | string
>;
resolve(data);
} else if (
typeof error === 'object' &&
error !== null
) {
const validationError =
error as FormValidationError;
if (validationError?.status === 400) {
resolve({
...validationError.data,
status: validationError.status.toString(),
});
}
}
} else if (result.data) {
resolve(result.data);
.then(({ error, data }) => {
return new Promise<Record<string, unknown>>((resolve) => {
if (
isFetchBaseQueryError(error) &&
isRecord(error.data)
) {
if (error.status === HttpStatus.FormNotComplete) {
resolve(error.data);
} else if (error.status === HttpStatus.BadRequest) {
resolve({
...error.data,
status: error.status,
});
}
} else if (data) {
resolve(data);
}

resolve({});
},
);
resolve({});
});
})
.catch((error) => {
return new Promise<Record<string, object>>(
Expand Down Expand Up @@ -146,6 +138,10 @@ export const WfoPydanticForm = ({

const wfoComponentMatcher: ComponentMatcher = (currentMatchers) => {
const wfoMatchers: PydanticComponentMatcher[] = [
...currentMatchers
.filter((matcher) => matcher.id !== 'text')
.filter((matcher) => matcher.id !== 'array')
.filter((matcher) => matcher.id !== 'object'),
{
id: 'textarea',
ElementMatch: {
Expand All @@ -159,6 +155,26 @@ export const WfoPydanticForm = ({
);
},
},
{
id: 'object',
ElementMatch: {
isControlledElement: false,
Element: WfoObjectField,
},
matcher: (field) => {
return field.type === PydanticFormFieldType.OBJECT;
},
},
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the defaultComponentMatcher in the pydantic-forms lib there are some other fields that match on field type array like the MultiSelectField. This matcher should be after defaut matchers or else they will hijack matches that should end up there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now the default object field matcher.

id: 'array',
ElementMatch: {
isControlledElement: true,
Element: WfoArrayField,
},
matcher: (field) => {
return field.type === PydanticFormFieldType.ARRAY;
},
},
{
id: 'summary',
ElementMatch: {
Expand Down Expand Up @@ -208,7 +224,6 @@ export const WfoPydanticForm = ({
return field.type === PydanticFormFieldType.BOOLEAN;
},
},
...currentMatchers.filter((matcher) => matcher.id !== 'text'),
{
id: 'text',
ElementMatch: {
Expand All @@ -221,8 +236,9 @@ export const WfoPydanticForm = ({
validator: zodValidationPresets.string,
},
];

return componentMatcher ? componentMatcher(wfoMatchers) : wfoMatchers;
return componentMatcherExtender
? componentMatcherExtender(wfoMatchers)
: wfoMatchers;
};

const handleCancel = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import type { PydanticFormElement } from 'pydantic-forms';
import { EuiFlexItem, EuiFormRow, EuiText } from '@elastic/eui';
import { tint } from '@elastic/eui';
import { css } from '@emotion/react';
import type { WfoTheme } from '@orchestrator-ui/orchestrator-ui-components';

import { getCommonFormFieldStyles } from '@/components/WfoForms/formFields/commonStyles';
import { useWithOrchestratorTheme } from '@/hooks';
import { getCommonFormFieldStyles } from '@/components';
import { WfoTheme, useWithOrchestratorTheme } from '@/hooks';

export const getStyles = ({ theme }: WfoTheme) => {
const toShadeColor = (color: string) => tint(color, 0.9);
Expand Down
Loading
Loading