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 committed Aug 29, 2024
1 parent 99dcd90 commit 2a130e0
Show file tree
Hide file tree
Showing 22 changed files with 357 additions and 391 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ A migration participant has been added to automatically keep compatible all diag
- https://github.com/eclipse-sirius/sirius-web/issues/3834[#3834] [deck] Add more variables for DeckDescription
- https://github.com/eclipse-sirius/sirius-web/issues/3897[#3897] [sirius-web] Improve the search for projects
- https://github.com/eclipse-sirius/sirius-web/issues/3902[#3902] [core] Move the Help menu entry at the last position (after any contributed entries)
- https://github.com/eclipse-sirius/sirius-web/issues/3758[#3758] [form] Store the payload of all form based representation in `FormContext`

== v2024.7.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,17 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
import { gql, useSubscription } from '@apollo/client';
import { RepresentationComponentProps, Toast } from '@eclipse-sirius/sirius-components-core';
import Typography from '@mui/material/Typography';
import { makeStyles } from 'tss-react/mui';
import { useMachine } from '@xstate/react';
import { RepresentationComponentProps } from '@eclipse-sirius/sirius-components-core';
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 Down Expand Up @@ -76,83 +51,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 } = 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]);

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);
},
});
}, [payload]);

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,32 +93,24 @@ 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') {
content = (
<div className={classes.complete}>
<Typography variant="h5" align="center">
The form does not exist anymore
</Typography>
</div>
);
}

return (
<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 2a130e0

Please sign in to comment.