/
index.tsx
165 lines (142 loc) · 3.4 KB
/
index.tsx
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/** @module Components.Project.Simulation.Materials.Add */
import { useCallback, useContext, useState } from 'react'
import { v4 as uuid } from 'uuid'
import { IModelMaterialsValue } from '@/models/index.d'
import {
IFrontSimulationsItem,
IFrontMutateSimulationsItem
} from '@/api/index.d'
import { NotificationContext } from '@/context/notification'
import { addError } from '@/context/notification/actions'
import { asyncFunctionExec } from '@/components/utils/asyncFunction'
import { AddButton } from '@/components/assets/button'
import Utils from '@/lib/utils'
import SimulationAPI from '@/api/simulation'
/**
* Props
*/
export type Simulation = Pick<IFrontSimulationsItem, 'id' | 'scheme'>
export type Swr = {
mutateOneSimulation: (
simulation: IFrontMutateSimulationsItem
) => Promise<void>
}
export interface Props {
simulation: Simulation
material: Partial<IModelMaterialsValue>
swr: Swr
onError: (desc?: string) => void
onClose: () => void
}
/**
* Errors
*/
export const errors = {
material: 'You need to define a material',
selected: 'You need to select a solid',
update: 'Unable to add material'
}
/**
* On add
* @param simulation Simulation
* @param material Material
* @param swr SWR
*/
export const _onAdd = async (
simulation: Simulation,
material: IModelMaterialsValue,
swr: Swr
): Promise<void> => {
// New material
const newMaterial = Utils.deepCopy(material)
// Set uuid
newMaterial.uuid = uuid()
// New simulation
const newSimulation = Utils.deepCopy(simulation)
// Update local
const materials = newSimulation.scheme.configuration.materials!
materials.values = [...(materials.values ?? []), newMaterial]
// Diff
const diff = {
...materials,
done: true
}
// API
await SimulationAPI.update({ id: simulation.id }, [
{
key: 'scheme',
type: 'json',
method: 'set',
path: ['configuration', 'materials'],
value: diff
}
])
await SimulationAPI.update({ id: simulation.id }, [
{
key: 'scheme',
type: 'json',
method: 'set',
path: ['configuration', 'run'],
value: {
...newSimulation.scheme.configuration.run,
done: false
}
}
])
// Local
await swr.mutateOneSimulation(newSimulation)
}
/**
* Add
* @param props Props
* @returns Add
*/
const Add: React.FunctionComponent<Props> = ({
simulation,
material,
swr,
onError,
onClose
}) => {
// State
const [loading, setLoading] = useState<boolean>(false)
// Context
const { dispatch } = useContext(NotificationContext)
/**
* On add
*/
const onAdd = useCallback((): void => {
asyncFunctionExec(async () => {
setLoading(true)
try {
// Check
if (!material.material) {
onError(errors.material)
setLoading(false)
return
}
if (!material.selected?.length) {
onError(errors.selected)
setLoading(false)
return
}
onError()
await _onAdd(simulation, material as IModelMaterialsValue, swr)
setLoading(false)
onClose()
} catch (err: any) {
dispatch(addError({ title: errors.update, err }))
setLoading(false)
}
})
}, [simulation, material, swr, onError, onClose, dispatch])
/**
* Render
*/
return (
<AddButton loading={loading} needMargin onAdd={onAdd}>
Add
</AddButton>
)
}
export default Add