File size: 4,073 Bytes
f277af2
 
db19895
 
04225e2
f277af2
 
 
 
db19895
f277af2
04225e2
 
 
 
 
 
 
 
b06739e
 
 
 
 
 
 
 
 
 
 
 
 
 
04225e2
f277af2
 
 
 
 
 
 
 
 
 
 
 
 
 
db19895
 
f277af2
db19895
 
f277af2
 
db19895
 
 
 
 
f277af2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
916a392
f277af2
db19895
916a392
 
db19895
f277af2
 
36669dc
f277af2
 
 
 
 
 
 
 
 
916a392
 
 
 
 
f277af2
916a392
f277af2
db19895
f277af2
 
 
36669dc
db19895
916a392
 
 
36669dc
db19895
916a392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36669dc
 
916a392
36669dc
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import get from 'lodash/get';
import omit from 'lodash/omit';
import { useCallback, useEffect } from 'react';
import { Edge, Node } from 'reactflow';
import { Operator } from '../constant';
import {
  ICategorizeItem,
  ICategorizeItemResult,
  IOperatorForm,
  NodeData,
} from '../interface';
import useGraphStore from '../store';

// exclude some nodes downstream of the classification node
const excludedNodes = [Operator.Categorize, Operator.Answer, Operator.Begin];

export const useBuildCategorizeToOptions = () => {
  const nodes = useGraphStore((state) => state.nodes);

  const buildCategorizeToOptions = useCallback(
    (toList: string[]) => {
      return nodes
        .filter(
          (x) =>
            excludedNodes.every((y) => y !== x.data.label) &&
            !toList.some((y) => y === x.id), // filter out selected values ​​in other to fields from the current drop-down box options
        )
        .map((x) => ({ label: x.id, value: x.id }));
    },
    [nodes],
  );

  return buildCategorizeToOptions;
};

/**
   * convert the following object into a list
   * 
   * {
      "product_related": {
      "description": "The question is about product usage, appearance and how it works.",
      "examples": "Why it always beaming?\nHow to install it onto the wall?\nIt leaks, what to do?",
      "to": "generate:0"
      }
      }
*/
const buildCategorizeListFromObject = (
  categorizeItem: ICategorizeItemResult,
  edges: Edge[],
  node?: Node<NodeData>,
) => {
  // Categorize's to field has two data sources, with edges as the data source.
  // Changes in the edge or to field need to be synchronized to the form field.
  return Object.keys(categorizeItem).reduce<Array<ICategorizeItem>>(
    (pre, cur) => {
      // synchronize edge data to the to field
      const edge = edges.find(
        (x) => x.source === node?.id && x.sourceHandle === cur,
      );
      pre.push({ name: cur, ...categorizeItem[cur], to: edge?.target });
      return pre;
    },
    [],
  );
};

/**
   * Convert the list in the following form into an object
   * {
    "items": [
      {
        "name": "Categorize 1",
        "description": "111",
        "examples": "ddd",
        "to": "Retrieval:LazyEelsStick"
      }
     ]
    }
*/
const buildCategorizeObjectFromList = (list: Array<ICategorizeItem>) => {
  return list.reduce<ICategorizeItemResult>((pre, cur) => {
    if (cur?.name) {
      pre[cur.name] = omit(cur, 'name');
    }
    return pre;
  }, {});
};

export const useHandleFormValuesChange = ({
  onValuesChange,
  form,
  nodeId,
}: IOperatorForm) => {
  const edges = useGraphStore((state) => state.edges);
  const getNode = useGraphStore((state) => state.getNode);
  const node = getNode(nodeId);

  const handleValuesChange = useCallback(
    (changedValues: any, values: any) => {
      console.info(changedValues, values);
      onValuesChange?.(changedValues, {
        ...omit(values, 'items'),
        category_description: buildCategorizeObjectFromList(values.items),
      });
    },
    [onValuesChange],
  );

  useEffect(() => {
    const items = buildCategorizeListFromObject(
      get(node, 'data.form.category_description', {}),
      edges,
      node,
    );
    form?.setFieldsValue({
      items,
    });
  }, [form, node, edges]);

  return { handleValuesChange };
};

export const useHandleToSelectChange = (nodeId?: string) => {
  const { addEdge, deleteEdgeBySourceAndSourceHandle } = useGraphStore(
    (state) => state,
  );
  const handleSelectChange = useCallback(
    (name?: string) => (value?: string) => {
      if (nodeId && name) {
        if (value) {
          addEdge({
            source: nodeId,
            target: value,
            sourceHandle: name,
            targetHandle: null,
          });
        } else {
          // clear selected value
          deleteEdgeBySourceAndSourceHandle({
            source: nodeId,
            sourceHandle: name,
          });
        }
      }
    },
    [addEdge, nodeId, deleteEdgeBySourceAndSourceHandle],
  );

  return { handleSelectChange };
};