Skip to content

Commit

Permalink
[3758] Store all form payload in a context
Browse files Browse the repository at this point in the history
Bug: #3758
Signed-off-by: Michaël Charfadi <[email protected]>
  • Loading branch information
mcharfadi authored and sbegaudeau committed Aug 29, 2024
1 parent 99dcd90 commit 1edf925
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 426 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,18 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { gql, useSubscription } from '@apollo/client';
import { RepresentationComponentProps, Toast } from '@eclipse-sirius/sirius-components-core';
import { RepresentationComponentProps } from '@eclipse-sirius/sirius-components-core';
import Typography from '@mui/material/Typography';
import { makeStyles } from 'tss-react/mui';
import { useMachine } from '@xstate/react';
import { useEffect, useState } from 'react';
import { makeStyles } from 'tss-react/mui';
import { FormContext } from '../contexts/FormContext';
import { Form } from '../form/Form';
import { formRefreshedEventPayloadFragment } from '../form/FormEventFragments';
import { GQLFormEventSubscription } from '../form/FormEventFragments.types';
import { GQLFormEventPayload } from '../form/FormEventFragments.types';
import { Page } from '../pages/Page';
import { ToolbarAction } from '../toolbaraction/ToolbarAction';
import { FormRepresentationState } from './FormRepresentation.types';
import {
FormRepresentationContext,
FormRepresentationEvent,
HandleCompleteEvent,
HandleSubscriptionResultEvent,
HideToastEvent,
SchemaValue,
ShowToastEvent,
SwitchFormEvent,
formRepresentationMachine,
} from './FormRepresentationMachine';

const formEventSubscription = gql(`
subscription formEvent($input: FormEventInput!) {
formEvent(input: $input) {
__typename
... on FormRefreshedEventPayload {
...formRefreshedEventPayloadFragment
}
}
}
${formRefreshedEventPayloadFragment}
`);
import { useFormSubscription } from './useFormSubscription';
import { GQLFormRefreshedEventPayload } from './useFormSubscription.types';

const useFormRepresentationStyles = makeStyles()((theme) => ({
page: {
Expand All @@ -61,6 +37,7 @@ const useFormRepresentationStyles = makeStyles()((theme) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
paddingTop: theme.spacing(8),
},
toolbar: {
display: 'flex',
Expand All @@ -76,83 +53,37 @@ const useFormRepresentationStyles = makeStyles()((theme) => ({
},
}));

/**
* Connect the Form component to the GraphQL API over Web Socket.
*/
const isFormRefreshedEventPayload = (payload: GQLFormEventPayload): payload is GQLFormRefreshedEventPayload =>
payload && payload.__typename === 'FormRefreshedEventPayload';

export const FormRepresentation = ({ editingContextId, representationId, readOnly }: RepresentationComponentProps) => {
const { classes } = useFormRepresentationStyles();
const [{ value, context }, dispatch] = useMachine<FormRepresentationContext, FormRepresentationEvent>(
formRepresentationMachine,
{
context: {
formId: representationId,
},
}
);
const { toast, formRepresentation } = value as SchemaValue;
const { id, formId, form, message } = context;
const [state, setState] = useState<FormRepresentationState>({
payload: null,
form: null,
});

/**
* Displays an other form if the selection indicates that we should display another properties view.
*/
const { payload, complete } = useFormSubscription(editingContextId, representationId);
useEffect(() => {
if (formId !== representationId) {
const switchFormEvent: SwitchFormEvent = { type: 'SWITCH_FORM', formId: representationId };
dispatch(switchFormEvent);
if (isFormRefreshedEventPayload(payload)) {
setState((prevState) => ({ ...prevState, form: payload.form }));
}
}, [representationId, formId, dispatch]);
}, [payload]);

const { error } = useSubscription<GQLFormEventSubscription>(formEventSubscription, {
variables: {
input: {
id,
editingContextId,
formId: representationId,
},
},
fetchPolicy: 'no-cache',
onData: ({ data }) => {
if (data.data) {
const { formEvent } = data.data;
setState((prevState) => ({ ...prevState, payload: formEvent }));
}
const handleDataEvent: HandleSubscriptionResultEvent = {
type: 'HANDLE_SUBSCRIPTION_RESULT',
result: data,
};
dispatch(handleDataEvent);
},
onComplete: () => {
const completeEvent: HandleCompleteEvent = { type: 'HANDLE_COMPLETE' };
dispatch(completeEvent);
},
});

useEffect(() => {
if (error) {
const { message } = error;
const showToastEvent: ShowToastEvent = { type: 'SHOW_TOAST', message };
dispatch(showToastEvent);
}
}, [error, dispatch]);
const { classes } = useFormRepresentationStyles();

let content: JSX.Element | null = null;
if (formRepresentation === 'ready') {
if (form.pages.length > 1) {
content = <Form editingContextId={editingContextId} form={form} readOnly={readOnly} />;
} else if (form.pages.length === 1) {
if (state.form) {
if (state.form.pages.length > 1) {
content = <Form editingContextId={editingContextId} form={state.form} readOnly={readOnly} />;
} else if (state.form.pages.length === 1) {
let selectedPageToolbar = null;
if (form.pages[0].toolbarActions?.length > 0) {
if (state.form.pages[0].toolbarActions?.length > 0) {
selectedPageToolbar = (
<div className={classes.toolbar}>
{form.pages[0].toolbarActions.map((toolbarAction) => (
{state.form.pages[0].toolbarActions.map((toolbarAction) => (
<div className={classes.toolbarAction} key={toolbarAction.id}>
<ToolbarAction
editingContextId={editingContextId}
formId={form.id}
formId={state.form.id}
readOnly={readOnly}
widget={toolbarAction}
/>
Expand All @@ -164,14 +95,21 @@ export const FormRepresentation = ({ editingContextId, representationId, readOnl
content = (
<div data-testid="page" className={classes.page}>
{selectedPageToolbar}
<Page editingContextId={editingContextId} formId={form.id} page={form.pages[0]} readOnly={readOnly} />
<Page
editingContextId={editingContextId}
formId={state.form.id}
page={state.form.pages[0]}
readOnly={readOnly}
/>
</div>
);
}
} else if (formRepresentation === 'complete') {
}

if (complete) {
content = (
<div className={classes.complete}>
<Typography variant="h5" align="center">
<Typography variant="h6" align="center">
The form does not exist anymore
</Typography>
</div>
Expand All @@ -182,14 +120,9 @@ export const FormRepresentation = ({ editingContextId, representationId, readOnl
<div data-representation-kind="form">
<FormContext.Provider
value={{
payload: state.payload,
payload: payload,
}}>
{content}
<Toast
message={message}
open={toast === 'visible'}
onClose={() => dispatch({ type: 'HIDE_TOAST' } as HideToastEvent)}
/>
</FormContext.Provider>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* Obeo - initial API and implementation
*******************************************************************************/

import { GQLFormEventPayload } from '../form/FormEventFragments.types';
import { GQLForm } from '../form/FormEventFragments.types';

export interface FormRepresentationState {
payload: GQLFormEventPayload | null;
form: GQLForm | null;
}

This file was deleted.

Loading

0 comments on commit 1edf925

Please sign in to comment.