• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

waldiez / react / 13032474932

29 Jan 2025 01:31PM UTC coverage: 89.816% (-0.3%) from 90.155%
13032474932

push

github

lazToum
prepare async mode views

2920 of 3211 branches covered (90.94%)

Branch coverage included in aggregate %.

128 of 260 new or added lines in 15 files covered. (49.23%)

3 existing lines in 2 files now uncovered.

16358 of 18253 relevant lines covered (89.62%)

245.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.65
/src/waldiez/containers/sidebar/modals/editFlowModal/hooks/useEditFlowModal.ts
1
/**
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2024 - 2025 Waldiez & contributors
4
 */
5
import { useEffect, useState } from "react";
1✔
6
import isEqual from "react-fast-compare";
1✔
7

8
import { SingleValue } from "@waldiez/components";
9
import {
10
    EditFlowModalData,
11
    EditFlowModalProps,
12
} from "@waldiez/containers/sidebar/modals/editFlowModal/types";
13
import { WaldiezEdge } from "@waldiez/models";
14
import { useWaldiez } from "@waldiez/store";
1✔
15

16
export const useEditFlowModal = (props: EditFlowModalProps) => {
1✔
17
    const { isOpen, onClose } = props;
58✔
18
    const getFlowInfo = useWaldiez(s => s.getFlowInfo);
58✔
19
    const updateFlowInfo = useWaldiez(s => s.updateFlowInfo);
58✔
20
    const updateFlowOrder = useWaldiez(s => s.updateFlowOrder);
58✔
21
    const updateFlowPrerequisites = useWaldiez(s => s.updateFlowPrerequisites);
58✔
22
    const flowInfo = getFlowInfo();
58✔
23
    const { name, description, requirements, tags, isAsync } = flowInfo;
58✔
24
    const [flowData, setFlowData] = useState<EditFlowModalData>({
58✔
25
        name,
58✔
26
        description,
58✔
27
        requirements,
58✔
28
        tags,
58✔
29
        isAsync,
58✔
30
    });
58✔
31
    const [selectedNewEdge, setSelectedNewEdge] = useState<WaldiezEdge | null>(null);
58✔
32
    const getFlowEdges = useWaldiez(s => s.getFlowEdges);
58✔
33
    const { used: sortedEdges, remaining: remainingEdges } = getFlowEdges(true);
58✔
34
    const onFlowChanged = useWaldiez(s => s.onFlowChanged);
58✔
35
    // tmp state (to save onSubmit, discard onCancel)
36
    const [sortedEdgesState, setSortedEdgesState] = useState<WaldiezEdge[]>(sortedEdges);
58✔
37
    const [remainingEdgesState, setRemainingEdgeState] = useState<WaldiezEdge[]>(remainingEdges);
58✔
38
    const isDataDirty = !isEqual(flowData, { name, description, requirements, tags, isAsync });
58✔
39
    const isEdgesDirty = !isEqual(sortedEdgesState, sortedEdges);
58✔
40
    const [isDirty, setIsDirty] = useState<boolean>(isDataDirty || isEdgesDirty);
58✔
41
    useEffect(() => {
58✔
42
        reset();
19✔
43
    }, [isOpen]);
58✔
44
    const onSubmit = () => {
58✔
45
        updateFlowInfo(flowData);
1✔
46
        if (!flowData.isAsync) {
1✔
47
            const edgeOrders = sortedEdgesState
1✔
48
                .map((edge, index) => ({
1✔
49
                    id: edge.id,
10✔
50
                    order: index,
10✔
51
                }))
1✔
52
                .concat(
1✔
53
                    remainingEdgesState.map(edge => ({
1✔
NEW
54
                        id: edge.id,
×
NEW
55
                        order: -1,
×
56
                    })),
1✔
57
                );
1✔
58
            updateFlowOrder(edgeOrders);
1✔
59
        } else {
1!
NEW
60
            updateFlowPrerequisites(sortedEdgesState);
×
NEW
61
        }
×
62
        onFlowChanged();
1✔
63
        setIsDirty(false);
1✔
64
    };
1✔
65
    const reset = () => {
58✔
66
        const { name, description, requirements, tags, isAsync } = getFlowInfo();
20✔
67
        setFlowData({ name, description, requirements, tags, isAsync });
20✔
68
        const { used, remaining } = getFlowEdges(true);
20✔
69
        setSortedEdgesState(used);
20✔
70
        setRemainingEdgeState(remaining);
20✔
71
        setIsDirty(false);
20✔
72
    };
20✔
73
    const onCancel = () => {
58✔
74
        reset();
1✔
75
        onClose();
1✔
76
    };
1✔
77
    const onDataChange = (partialData: Partial<EditFlowModalData>) => {
58✔
78
        const isDataDirty = !isEqual(
12✔
79
            { ...flowData, ...partialData },
12✔
80
            { name, description, requirements, tags, isAsync },
12✔
81
        );
12✔
82
        const isEdgesDirty = !isEqual(sortedEdgesState, sortedEdges);
12✔
83
        setFlowData({ ...flowData, ...partialData });
12✔
84
        setIsDirty(isDataDirty || isEdgesDirty);
12!
85
    };
12✔
86
    const onSelectedNewEdgeChange = (option: SingleValue<{ label: string; value: WaldiezEdge }>) => {
58✔
87
        if (option) {
1✔
88
            setSelectedNewEdge(option.value);
1✔
89
        }
1✔
90
    };
1✔
91
    const getNewEdgeOrder = () => {
58✔
92
        // find the last order
93
        let lastOrder = sortedEdgesState[sortedEdgesState.length - 1]?.data?.order;
1✔
94
        if (lastOrder === undefined) {
1!
95
            lastOrder = sortedEdgesState.length;
×
96
        } else {
1✔
97
            lastOrder++;
1✔
98
        }
1✔
99
        if (lastOrder < 0) {
1!
100
            lastOrder = 0;
×
101
        }
×
102
        return lastOrder;
1✔
103
    };
1✔
104
    const onAddEdge = () => {
58✔
105
        if (!selectedNewEdge) {
1!
106
            return;
×
107
        }
×
108
        // it should be in the 'remaining' list
109
        if (remainingEdgesState.find(e => e.id === selectedNewEdge.id)) {
1✔
110
            const lastOrder = getNewEdgeOrder();
1✔
111
            const newSelectedEdge = {
1✔
112
                ...selectedNewEdge,
1✔
113
                data: { ...selectedNewEdge.data, order: lastOrder } as any,
1✔
114
            };
1✔
115
            setSortedEdgesState([...sortedEdgesState, newSelectedEdge]);
1✔
116
            setRemainingEdgeState(remainingEdgesState.filter(e => e.id !== selectedNewEdge.id));
1✔
117
            setSelectedNewEdge(null);
1✔
118
            setIsDirty(true);
1✔
119
        }
1✔
120
    };
1✔
121
    const onRemoveEdge = (edge: WaldiezEdge) => {
58✔
122
        // avoid having zero edges/chats in the flow
123
        if (sortedEdgesState.length === 1) {
1!
124
            return;
×
125
        }
×
126
        // it should be in the 'sorted' list
127
        if (sortedEdgesState.find(e => e.id === edge.id)) {
1✔
128
            // set the order to -1
129
            // edge.data = { ...edge.data, order: -1 } as any;
130
            setSortedEdgesState(sortedEdgesState.filter(e => e.id !== edge.id));
1✔
131
            setRemainingEdgeState([
1✔
132
                ...remainingEdgesState,
1✔
133
                { ...edge, data: { ...edge.data, order: -1, prerequisites: [] } as any },
1✔
134
            ]);
1✔
135
            setIsDirty(true);
1✔
136
        }
1✔
137
    };
1✔
138
    const onMoveEdgeUp = (index: number) => {
58✔
139
        // it should be in the 'sorted' list
140
        if (sortedEdgesState.find(e => e.id === sortedEdgesState[index].id)) {
1✔
141
            // swap the order between the current and the previous edge
142
            const previousEdge = sortedEdgesState[index - 1];
1✔
143
            const currentEdge = sortedEdgesState[index];
1✔
144
            const newSortedEdges = sortedEdgesState.slice();
1✔
145
            newSortedEdges[index - 1] = currentEdge;
1✔
146
            newSortedEdges[index] = previousEdge;
1✔
147
            setSortedEdgesState(setSyncPrerequisites(newSortedEdges));
1✔
148
            // setSortedEdgesState(newSortedEdges);
149
            setIsDirty(true);
1✔
150
        }
1✔
151
    };
1✔
152
    const setSyncPrerequisites = (newSortedEdges: WaldiezEdge[]) => {
58✔
153
        // if order > 0: set the prerequisites to the previous [edge.id]
154
        // if order === 0: set the prerequisites to []
155
        return newSortedEdges.map((edge, index) => {
2✔
156
            if (index === 0) {
14✔
157
                return { ...edge, data: { ...edge.data, order: 0, prerequisites: [] } } as WaldiezEdge;
2✔
158
            }
2✔
159
            const previousEdge = newSortedEdges[index - 1];
12✔
160
            return {
12✔
161
                ...edge,
12✔
162
                data: {
12✔
163
                    ...edge.data,
12✔
164
                    order: index,
12✔
165
                    prerequisites: [previousEdge.id],
12✔
166
                },
12✔
167
            } as WaldiezEdge;
12✔
168
        });
2✔
169
    };
2✔
170
    const onPrerequisitesChange = (edge: WaldiezEdge, prerequisites: string[]) => {
58✔
NEW
171
        const newSortedEdges = sortedEdgesState.map(e => {
×
NEW
172
            if (e.id === edge.id) {
×
NEW
173
                return { ...e, data: { ...e.data, prerequisites } } as WaldiezEdge;
×
NEW
174
            }
×
NEW
175
            return e;
×
NEW
176
        });
×
NEW
177
        setSortedEdgesState(newSortedEdges);
×
NEW
178
        setIsDirty(true);
×
NEW
179
    };
×
180
    const onMoveEdgeDown = (index: number) => {
58✔
181
        // it should be in the 'sorted' list
182
        if (sortedEdgesState.find(e => e.id === sortedEdgesState[index].id)) {
1✔
183
            // swap the order between the current and the next edge
184
            const nextEdge = sortedEdgesState[index + 1];
1✔
185
            const nextOrder = nextEdge.data?.order;
1✔
186
            const currentEdge = sortedEdgesState[index];
1✔
187
            const currentOrder = currentEdge.data?.order;
1✔
188
            const newSortedEdges = sortedEdgesState.slice();
1✔
189
            newSortedEdges[index + 1] = {
1✔
190
                ...currentEdge,
1✔
191
                data: { ...currentEdge.data, order: nextOrder },
1✔
192
            } as WaldiezEdge;
1✔
193
            newSortedEdges[index] = {
1✔
194
                ...nextEdge,
1✔
195
                data: { ...nextEdge.data, order: currentOrder },
1✔
196
            } as WaldiezEdge;
1✔
197
            setSortedEdgesState(setSyncPrerequisites(newSortedEdges));
1✔
198
            setIsDirty(true);
1✔
199
        }
1✔
200
    };
1✔
201
    return {
58✔
202
        flowData,
58✔
203
        isOpen,
58✔
204
        sortedEdgesState,
58✔
205
        remainingEdgesState,
58✔
206
        selectedNewEdge,
58✔
207
        isDirty,
58✔
208
        onClose,
58✔
209
        onSubmit,
58✔
210
        onCancel,
58✔
211
        onDataChange,
58✔
212
        onSelectedNewEdgeChange,
58✔
213
        onAddEdge,
58✔
214
        onRemoveEdge,
58✔
215
        onMoveEdgeUp,
58✔
216
        onMoveEdgeDown,
58✔
217
        onPrerequisitesChange,
58✔
218
    };
58✔
219
};
58✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc