From cac8f820472cf806cb6cd75966420f3bad43a987 Mon Sep 17 00:00:00 2001 From: rlazarini <remi.lazarini@cea.fr> Date: Fri, 9 Feb 2024 09:01:27 +0100 Subject: [PATCH] [ivette] add hook useServerField --- ivette/src/frama-c/states.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ivette/src/frama-c/states.ts b/ivette/src/frama-c/states.ts index 13644db3a40..ba057a54d12 100644 --- a/ivette/src/frama-c/states.ts +++ b/ivette/src/frama-c/states.ts @@ -37,6 +37,7 @@ import { GlobalState, useGlobalState } from 'dome/data/states'; import { Client, useModel } from 'dome/table/models'; import { CompactModel } from 'dome/table/arrays'; import * as Ast from 'frama-c/kernel/api/ast'; +import { FieldState, FieldError } from 'dome/layout/forms'; import * as Server from './server'; // -------------------------------------------------------------------------- @@ -307,6 +308,34 @@ export function useSyncValue<A>(value: Value<A>): A | undefined { return v; } +/** Synchronize FieldState and server state only if there is no error. */ +export function useServerField<A>( + state: State<A>, + defaultValue: A, +): FieldState<A> { + const [value, setState] = useSyncState(state); + const [localValue, setLocalValue] = React.useState(value); + const [localError, setLocalError] = React.useState<FieldError>(undefined); + + React.useEffect(() => { + !localError && setLocalValue(value); + }, [value, localError]); + + const update = React.useCallback((newValue: A, newError: FieldError) => { + setLocalValue(newValue); + setLocalError(newError); + if (!newError) { + setState(newValue); + } + }, [setState]); + + return { + value: localValue ?? defaultValue, + error: localError, + onChanged: update + }; +} + // -------------------------------------------------------------------------- // --- Synchronized Arrays // -------------------------------------------------------------------------- -- GitLab