@@ -10,8 +10,9 @@ import {
1010} from '@irontec/ivoz-ui/components/shared/Button/Button.styles' ;
1111import {
1212 ActionFunctionComponent ,
13- GlobalActionItemProps ,
13+ ActionItemProps ,
1414 isSingleRowAction ,
15+ MultiSelectActionItemProps ,
1516} from '@irontec/ivoz-ui/router/routeMapParser' ;
1617import { StyledTextField } from '@irontec/ivoz-ui/services/form/Field/TextField/TextField.styles' ;
1718import _ from '@irontec/ivoz-ui/services/translations/translate' ;
@@ -47,14 +48,25 @@ type SimulateCallResponseType = {
4748} ;
4849
4950const SimulateCall : ActionFunctionComponent = (
50- props : GlobalActionItemProps
51+ props : MultiSelectActionItemProps | ActionItemProps
5152) => {
53+ const {
54+ selectedValues = [ ] ,
55+ rows = [ ] ,
56+ variant = 'icon' ,
57+ } = props as MultiSelectActionItemProps ;
58+ const { row } = props as ActionItemProps ;
59+ const isSingleRow = isSingleRowAction ( props ) ;
60+
5261 /* eslint-disable react-hooks/rules-of-hooks */
53- if ( isSingleRowAction ( props ) ) {
62+ if ( isSingleRow ) {
5463 return < span className = 'display-none' > </ span > ;
5564 }
5665
57- const { rows, variant = 'icon' } = props ;
66+ const selectedIds =
67+ selectedValues . length > 0
68+ ? selectedValues
69+ : rows . map ( ( row ) => row . id . toString ( ) ) ;
5870
5971 const [ open , setOpen ] = useState ( false ) ;
6072 const [ error , setError ] = useState ( false ) ;
@@ -86,11 +98,12 @@ const SimulateCall: ActionFunctionComponent = (
8698 } ;
8799
88100 const handleUpdate = ( ) => {
101+ setCost ( undefined ) ;
89102 const promises = [ ] ;
90- for ( const row of rows ) {
103+ for ( const id of selectedIds ) {
91104 promises . push (
92105 apiPost ( {
93- path : `${ RatingPlanGroup . path } /${ row . id } /simulate_call` ,
106+ path : `${ RatingPlanGroup . path } /${ id } /simulate_call` ,
94107 values : {
95108 number : phoneNumber ,
96109 duration,
@@ -101,15 +114,33 @@ const SimulateCall: ActionFunctionComponent = (
101114 ) ;
102115 }
103116
104- Promise . all ( promises )
105- . then ( ( values ) => {
106- setCost ( values . map ( ( row ) => row . data as SimulateCallResponseType ) ) ;
107- } )
108- . catch ( ( error ) => {
109- console . error ( 'error' , error ) ;
110- setError ( true ) ;
111- setErrorMsg ( error . data . detail || error . data . title ) ;
117+ Promise . allSettled ( promises ) . then ( ( results ) => {
118+ const successfulResults : SimulateCallResponseType [ ] = [ ] ;
119+ const errorMessages : string [ ] = [ ] ;
120+
121+ results . forEach ( ( result , index ) => {
122+ if ( result . status === 'fulfilled' ) {
123+ successfulResults . push ( result . value . data ) ;
124+ } else {
125+ const errorDetail = result . reason ?. data ?. detail ;
126+ if ( errorDetail ) {
127+ errorMessages . push ( `Plan ID ${ selectedIds [ index ] } : ${ errorDetail } ` ) ;
128+ }
129+ }
112130 } ) ;
131+
132+ if ( successfulResults . length > 0 ) {
133+ setCost ( successfulResults ) ;
134+ setError ( false ) ;
135+ setErrorMsg ( '' ) ;
136+ } else if ( errorMessages . length > 0 ) {
137+ setError ( true ) ;
138+ setErrorMsg (
139+ _ ( 'No rating plan group can rate a call to introduced destination' )
140+ ) ;
141+ setCost ( undefined ) ;
142+ }
143+ } ) ;
113144 } ;
114145
115146 const boxStyles = {
@@ -146,84 +177,80 @@ const SimulateCall: ActionFunctionComponent = (
146177 { _ ( 'Simulate call' ) } { cost ? `(${ phoneNumber } )` : '' }
147178 </ DialogTitle >
148179 < DialogContent sx = { { textAlign : 'left!important' } } >
149- { ! error && (
150- < >
151- { ! cost && (
152- < Box >
153- < Box sx = { boxStyles } >
154- < StyledTextField
155- type = 'text'
156- required = { true }
157- label = { _ ( 'Phone number' ) }
158- placeholder = '+34987654321'
159- value = { phoneNumber }
160- onChange = { ( event ) => {
161- const { value } = event . target ;
162- setPhoneNumber ( value ) ;
163- } }
164- hasChanged = { false }
165- />
166- </ Box >
167- < Box sx = { boxStyles } >
168- < StyledTextField
169- type = 'number'
170- required = { true }
171- label = { _ ( 'Duration (seconds)' ) }
172- value = { duration }
173- onChange = { ( event ) => {
174- const { value } = event . target ;
175- setDuration ( parseInt ( value , 10 ) ) ;
176- } }
177- hasChanged = { false }
178- />
179- </ Box >
180- </ Box >
181- ) }
182- { cost && (
183- < Box >
184- < StyledTable size = 'small' >
185- < TableHead >
186- < TableRow >
187- < TableCell > { _ ( 'Plan' ) } </ TableCell >
188- < TableCell > { _ ( 'Start time' ) } </ TableCell >
189- < TableCell > { _ ( 'Duration' ) } </ TableCell >
190- < TableCell > { _ ( 'Destination' ) } </ TableCell >
191- < TableCell > { _ ( 'Connection fee' ) } </ TableCell >
192- < TableCell > { _ ( 'Interval start' ) } </ TableCell >
193- < TableCell > { _ ( 'Price' ) } </ TableCell >
194- < TableCell > { _ ( 'Total' ) } </ TableCell >
180+ { ! error && ! cost && (
181+ < Box >
182+ < Box sx = { boxStyles } >
183+ < StyledTextField
184+ type = 'text'
185+ required = { true }
186+ label = { _ ( 'Phone number' ) }
187+ placeholder = '+34987654321'
188+ value = { phoneNumber }
189+ onChange = { ( event ) => {
190+ const { value } = event . target ;
191+ setPhoneNumber ( value ) ;
192+ } }
193+ hasChanged = { false }
194+ />
195+ </ Box >
196+ < Box sx = { boxStyles } >
197+ < StyledTextField
198+ type = 'number'
199+ required = { true }
200+ label = { _ ( 'Duration (seconds)' ) }
201+ value = { duration }
202+ onChange = { ( event ) => {
203+ const { value } = event . target ;
204+ setDuration ( parseInt ( value , 10 ) ) ;
205+ } }
206+ hasChanged = { false }
207+ />
208+ </ Box >
209+ </ Box >
210+ ) }
211+ { cost && cost . length > 0 && (
212+ < Box >
213+ < StyledTable size = 'small' >
214+ < TableHead >
215+ < TableRow >
216+ < TableCell > { _ ( 'Plan' ) } </ TableCell >
217+ < TableCell > { _ ( 'Start time' ) } </ TableCell >
218+ < TableCell > { _ ( 'Duration' ) } </ TableCell >
219+ < TableCell > { _ ( 'Destination' ) } </ TableCell >
220+ < TableCell > { _ ( 'Connection fee' ) } </ TableCell >
221+ < TableCell > { _ ( 'Interval start' ) } </ TableCell >
222+ < TableCell > { _ ( 'Price' ) } </ TableCell >
223+ < TableCell > { _ ( 'Total' ) } </ TableCell >
224+ </ TableRow >
225+ </ TableHead >
226+ < TableBody >
227+ { cost . map ( ( row , idx ) => {
228+ const rate = row . rate
229+ ? `${ row . rate } ${ row . currencySymbol } / ${ row . ratePeriod } `
230+ : '' ;
231+
232+ return (
233+ < TableRow key = { idx } >
234+ < TableCell > { row . plan } </ TableCell >
235+ < TableCell > { row . callDate } </ TableCell >
236+ < TableCell > { row . duration } </ TableCell >
237+ < TableCell > { row . patternName } </ TableCell >
238+ < TableCell >
239+ { row . connectionCharge } { row . currencySymbol }
240+ </ TableCell >
241+ < TableCell > { row . intervalStart } </ TableCell >
242+ < TableCell >
243+ { rate } { rate ? _ ( 'Seconds' ) : '' }
244+ </ TableCell >
245+ < TableCell >
246+ { row . totalCost } { row . currencySymbol }
247+ </ TableCell >
195248 </ TableRow >
196- </ TableHead >
197- < TableBody >
198- { cost . map ( ( row , idx ) => {
199- const rate = row . rate
200- ? `${ row . rate } ${ row . currencySymbol } / ${ row . ratePeriod } `
201- : '' ;
202-
203- return (
204- < TableRow key = { idx } >
205- < TableCell > { row . plan } </ TableCell >
206- < TableCell > { row . callDate } </ TableCell >
207- < TableCell > { row . duration } </ TableCell >
208- < TableCell > { row . patternName } </ TableCell >
209- < TableCell >
210- { row . connectionCharge } { row . currencySymbol }
211- </ TableCell >
212- < TableCell > { row . intervalStart } </ TableCell >
213- < TableCell >
214- { rate } { rate ? _ ( 'Seconds' ) : '' }
215- </ TableCell >
216- < TableCell >
217- { row . totalCost } { row . currencySymbol }
218- </ TableCell >
219- </ TableRow >
220- ) ;
221- } ) }
222- </ TableBody >
223- </ StyledTable >
224- </ Box >
225- ) }
226- </ >
249+ ) ;
250+ } ) }
251+ </ TableBody >
252+ </ StyledTable >
253+ </ Box >
227254 ) }
228255 { error && < ErrorMessageComponent message = { errorMsg } /> }
229256 </ DialogContent >
0 commit comments