From b4ea726e80c59bbce9f3e5de4b59165416f6a058 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 7 Dec 2023 03:23:29 -0500
Subject: streamlined version of infoui fsa

---
 .../CollectionFreeFormInfoState.tsx                | 73 ++++++++++++++++++----
 1 file changed, 61 insertions(+), 12 deletions(-)

(limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx')

diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index 9090d0ea5..3af5a6c4b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -3,30 +3,79 @@ import { observer } from 'mobx-react';
 import './CollectionFreeFormView.scss';
 import React = require('react');
 
-export type infoArc = {
-    events: () => any;
-    actions: (arg?: any) => any;
-};
-export type infoState = {
-    Message: string;
-    Arcs: infoArc[];
-};
+/**
+ * An Fsa Arc.  The first array element is a test condition function that will be observed.
+ * The second array element is a function that will be invoked when the first test function
+ * returns a truthy value
+ */
+export type infoArc = [() => any, (res?: any) => infoState];
+
+export const StateMessage = Symbol('StateMessage');
+export const StateEntryFunc = Symbol('StateEntryFunc');
+export class infoState {
+    [StateMessage]: string = '';
+    [StateEntryFunc]?: () => any;
+    [key: string]: infoArc;
+    constructor(message: string, arcs: { [key: string]: infoArc }, entryFunc?: () => any) {
+        this[StateMessage] = message;
+        Object.assign(this, arcs);
+        this[StateEntryFunc] = entryFunc;
+    }
+}
+
+/**
+ * Create an FSA state.
+ * @param msg the message displayed when in this state
+ * @param arcs an object with fields containing @infoArcs (an object with field names indicating the arc transition and
+ * field values being a tuple of an arc transition trigger function (that returns a truthy value when the arc should fire),
+ * and an arc transition action function (that sets the next state)
+ * @param entryFunc a function to call when entering the state
+ * @returns an FSA state
+ */
+export function InfoState(
+    msg: string, //
+    arcs: { [key: string]: infoArc },
+    entryFunc?: () => any
+) {
+    return new infoState(msg, arcs, entryFunc);
+}
 
 export interface CollectionFreeFormInfoStateProps {
-    state: infoState;
+    infoState: infoState;
+    next: (state: infoState) => any;
 }
 
 @observer
 export class CollectionFreeFormInfoState extends React.Component<CollectionFreeFormInfoStateProps> {
     _disposers: IReactionDisposer[] = [];
 
+    get State() {
+        return this.props.infoState;
+    }
+    get Arcs() {
+        return Object.keys(this.State).map(key => this.State[key]);
+    }
+
     clearState = () => this._disposers.map(disposer => disposer());
-    initState = () => (this._disposers = this.props.state.Arcs.map(arc => reaction(arc.events, arc.actions, { fireImmediately: true })));
+    initState = () =>
+        (this._disposers = this.Arcs.map(arc => ({ test: arc[0], act: arc[1] })).map(arc => {
+            return reaction(
+                //
+                arc.test,
+                res => {
+                    if (res) {
+                        const next = arc.act(res);
+                        this.props.next(next);
+                    }
+                },
+                { fireImmediately: true }
+            );
+        }));
 
     componentDidMount(): void {
         this.initState();
     }
-    componentWillUpdate() {
+    componentDidUpdate() {
         this.clearState();
         this.initState();
     }
@@ -34,6 +83,6 @@ export class CollectionFreeFormInfoState extends React.Component<CollectionFreeF
         this.clearState();
     }
     render() {
-        return <div className="infoUI">{this.props.state.Message}</div>;
+        return <div className="infoUI">{this.State[StateMessage]}</div>;
     }
 }
-- 
cgit v1.2.3-70-g09d2

