11import React , { useState } from 'react' ;
2- import { connect } from 'react-redux' ;
3- import { Link } from 'react-router-dom' ;
2+ import { useSelector , useDispatch } from 'react-redux' ;
3+ import { Link , useParams , useNavigate } from 'react-router-dom' ;
44import _ from 'lodash' ;
55
66import { ACTION_TYPE , canPropertyBeMaintained , HELP_TEXTS } from './UpdateConfirmation' ;
77import { allowedValuesByQuality } from './UnitDetails' ;
88import ObservationItem from './ObservationItem' ;
99import { unitObservableProperties } from '../lib/municipalServicesClient' ;
10- import { withRouter } from '../hooks' ;
1110import * as constants from '../constants/index' ;
1211import * as actions from '../actions/index' ;
12+ import { RootState } from '../reducers/types' ;
13+ import { Unit , ObservableProperty , AllowedValue , UnitObservation } from '../types' ;
1314
1415import { QUALITIES } from './utils' ;
1516
16- const UnitMassEdit = ( props ) => {
17- const { units, groupId, observableProperty, allowedValues, enqueueObservation, navigate } = props ;
18- const [ formValues , setFormValues ] = useState ( {
17+ interface FormValues {
18+ units : string [ ] ;
19+ quality : string ;
20+ observationType : string ;
21+ notice : string ;
22+ }
23+
24+ // Extended AllowedValue type with property for internal use
25+ type AllowedValueWithProperty = AllowedValue & {
26+ property : string ;
27+ } ;
28+
29+ const UnitMassEdit : React . FC = ( ) => {
30+ const dispatch = useDispatch ( ) ;
31+ const navigate = useNavigate ( ) ;
32+ const params = useParams < { groupId : string ; propertyId : string } > ( ) ;
33+
34+ const unit = useSelector ( ( state : RootState ) => state . data . unit ) ;
35+ const service = useSelector ( ( state : RootState ) => state . data . service ) ;
36+ const serviceGroup = useSelector ( ( state : RootState ) => state . serviceGroup ) ;
37+
38+ const [ formValues , setFormValues ] = useState < FormValues > ( {
1939 units : [ ] ,
2040 quality : '' ,
2141 observationType : '' ,
2242 notice : ''
2343 } ) ;
44+
45+ if ( ! params . groupId || ! params . propertyId ) {
46+ return < div > Virheellinen parametrit</ div > ;
47+ }
48+
49+ const { groupId, propertyId } = params ;
50+ const onlyQualityProperties = serviceGroup !== constants . SERVICE_GROUPS . swimming . id ;
51+ const units = unit ? _ . filter ( unit , ( u : Unit ) => u . extensions ?. maintenance_group === groupId ) : undefined ;
52+
53+ let allowedValues : Record < string , Record < string , AllowedValue [ ] > > = { } ;
54+ let unitsIncludingSelectedProperty : Unit [ ] = [ ] ;
55+ let observableProperty : ObservableProperty | undefined ;
56+
57+ if ( units ) {
58+ units . forEach ( ( u : Unit ) => {
59+ const allObservableProperties = unitObservableProperties ( u , service , onlyQualityProperties ) ;
60+ const selectedObservableProperty = _ . filter ( allObservableProperties , ( op : ObservableProperty ) => op . id === propertyId ) ;
61+ const selectedObservablePropertyId = selectedObservableProperty [ 0 ] ?. id ;
62+ if ( selectedObservablePropertyId === propertyId ) {
63+ unitsIncludingSelectedProperty . push ( u ) ;
64+ if ( selectedObservableProperty [ 0 ] ) {
65+ observableProperty = selectedObservableProperty [ 0 ] ;
66+ }
67+ }
68+ } ) ;
69+ }
70+
71+ if ( observableProperty ) {
72+ allowedValues = { [ observableProperty . id ] : allowedValuesByQuality ( observableProperty ) } ;
73+ }
74+
2475 const unitsHeader = 'Valitse päivitettävät paikat' ;
25- const qualityHeader = observableProperty . name ? observableProperty . name . fi : 'Kuntotilanne' ;
76+ const qualityHeader = observableProperty ? .name ? observableProperty . name . fi : 'Kuntotilanne' ;
2677 const observationHeader = 'Vahvista valinta' ;
2778 const noticeHeader = 'Päivitä kuntokuvaus' ;
2879 const hasUnitsSelected = ! ! formValues . units . length ;
2980 const hasQualitySelected = ! ! formValues . quality ;
3081 const hasObservationTypeSelected = ! ! formValues . observationType ;
3182 const submitEnabled = hasUnitsSelected && hasQualitySelected && hasObservationTypeSelected ;
3283
33- function handleChange ( event ) {
34- const { value, name, checked, type } = event . target ;
84+ function handleChange ( event : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) {
85+ const target = event . target as HTMLInputElement ;
86+ const { value, name, checked, type } = target ;
3587
3688 if ( type === 'checkbox' ) {
37- let newChoices = [ ...formValues [ name ] ] ;
89+ let newChoices = [ ...formValues [ name as keyof FormValues ] as string [ ] ] ;
3890 newChoices = newChoices . filter ( e => e !== value ) ;
3991 if ( checked ) {
4092 newChoices . push ( value ) ;
@@ -60,26 +112,29 @@ const UnitMassEdit = (props) => {
60112 }
61113 }
62114
63- function allowedValue ( ) {
115+ function allowedValue ( ) : AllowedValueWithProperty | undefined {
64116 if ( ! observableProperty || ! formValues ?. quality ) return undefined ;
65117
66- return _ . find ( observableProperty . allowed_values , ( value ) => {
67- value . property = observableProperty . id ;
68- return ( value . identifier == formValues . quality ) ;
69- } ) ;
118+ return _ . find ( observableProperty . allowed_values , ( value : AllowedValue ) => {
119+ const valueWithProperty = value as AllowedValueWithProperty ;
120+ valueWithProperty . property = observableProperty . id ;
121+ return value . identifier === formValues . quality ;
122+ } ) as AllowedValueWithProperty | undefined ;
70123 }
71124
72125 function onSubmit ( ) {
73- const propertyId = observableProperty ?. id ;
126+ if ( ! observableProperty ) return ;
127+
128+ const propertyId = observableProperty . id ;
74129 const unitIds = formValues . units ;
75130 const value = allowedValue ( ) ;
76131 const isServiced = formValues . observationType === 'serviced' ;
77132 const notice = formValues . notice ;
78133
79- unitIds . forEach ( ( unitId ) => {
80- enqueueObservation ( propertyId , value , Number . parseInt ( unitId ) , isServiced ) ;
134+ unitIds . forEach ( ( unitId : string ) => {
135+ dispatch ( ( actions . enqueueObservation as any ) ( propertyId , value ?. identifier || '' , Number . parseInt ( unitId , 10 ) , isServiced ) ) ;
81136 if ( notice ) {
82- enqueueObservation ( 'notice' , notice , Number . parseInt ( unitId ) ) ;
137+ dispatch ( ( actions . enqueueObservation as any ) ( 'notice' , notice , Number . parseInt ( unitId , 10 ) ) ) ;
83138 }
84139 } ) ;
85140
@@ -90,10 +145,10 @@ const UnitMassEdit = (props) => {
90145 return < div > Ladataan...</ div > ;
91146 }
92147
93- const renderUnitInputs = _ . map ( _ . sortBy ( units , [ ( u ) => u . name . fi ] ) , ( unit ) => {
148+ const renderUnitInputs = _ . map ( _ . sortBy ( unitsIncludingSelectedProperty , [ ( u : Unit ) => u . name . fi ] ) , ( unit : Unit ) => {
94149 const observations = _ . map (
95- unit . observations ,
96- ( obs ) => { return < ObservationItem key = { obs . id } observation = { obs } /> ; }
150+ unit . observations || [ ] ,
151+ ( obs : UnitObservation ) => { return < ObservationItem key = { obs . id } observation = { obs } /> ; }
97152 ) ;
98153 return (
99154 < div key = { unit . id } className = "mass-edit-checkbox" >
@@ -113,40 +168,43 @@ const UnitMassEdit = (props) => {
113168 ) ;
114169 } ) ;
115170
116- const renderQualityInputs = ( ) => {
117- let values = [ ] ;
171+ const renderQualityInputs = ( ) : React . ReactElement [ ] => {
172+ if ( ! observableProperty ) return [ ] ;
173+
174+ let values : React . ReactElement [ ] = [ ] ;
118175
119- _ . each ( QUALITIES , ( quality ) => {
120- values = values . concat ( _ . map ( allowedValues [ observableProperty . id ] [ quality ] , ( v ) => {
176+ _ . each ( QUALITIES , ( quality : string ) => {
177+ const qualityValues = allowedValues [ observableProperty . id ] ?. [ quality ] || [ ] ;
178+ values = values . concat ( _ . map ( qualityValues , ( v : AllowedValue ) => {
121179 return (
122180 < div key = { v . identifier } className = "mass-edit-radio" >
123181 < input
124182 type = "radio"
125183 value = { v . identifier }
126184 name = "quality"
127- id = { `id-${ v . property } -${ v . identifier } ` }
185+ id = { `id-${ observableProperty . id } -${ v . identifier } ` }
128186 checked = { formValues . quality === v . identifier }
129187 onChange = { handleChange }
130188 disabled = { ! hasUnitsSelected }
131189 />
132- < label htmlFor = { `id-${ v . property } -${ v . identifier } ` } > { v . name . fi } </ label >
190+ < label htmlFor = { `id-${ observableProperty . id } -${ v . identifier } ` } > { v . name . fi } </ label >
133191 </ div >
134- )
192+ ) ;
135193 } ) ) ;
136194 } ) ;
137195
138196 return values ;
139- }
197+ } ;
140198
141- const renderConfirmation = ( ) => {
199+ const renderConfirmation = ( ) : React . ReactElement | undefined => {
142200 const value = allowedValue ( ) ;
143201
144202 if ( ! value ) return ;
145203
146- const render = ( ) => {
204+ const render = ( ) : React . ReactElement => {
147205 const quality = value . quality ;
148206
149- const observedOption = ( showHelpText = true ) => (
207+ const observedOption = ( showHelpText : boolean = true ) : React . ReactElement => (
150208 < div className = "mass-edit-radio" >
151209 < input
152210 type = "radio"
@@ -179,7 +237,7 @@ const UnitMassEdit = (props) => {
179237 ) ;
180238
181239 if ( canPropertyBeMaintained ( value . property ) && (
182- quality === 'good' || quality == 'satisfactory' || value . identifier == 'event' )
240+ quality === 'good' || quality === 'satisfactory' || value . identifier = == 'event' )
183241 ) {
184242 return (
185243 < >
@@ -202,7 +260,7 @@ const UnitMassEdit = (props) => {
202260 ) ;
203261 } ;
204262
205- const renderNoticeField = ( ) => (
263+ const renderNoticeField = ( ) : React . ReactElement => (
206264 < div className = "panel panel-default" >
207265 < div className = "panel-heading" > { noticeHeader } </ div >
208266 < div className = "panel-body" >
@@ -212,7 +270,7 @@ const UnitMassEdit = (props) => {
212270 id = "notice"
213271 name = "notice"
214272 className = "form-control"
215- rows = "3"
273+ rows = { 3 }
216274 value = { formValues . notice }
217275 onChange = { handleChange }
218276 disabled = { ! hasUnitsSelected }
@@ -244,8 +302,7 @@ const UnitMassEdit = (props) => {
244302 < div className = "panel panel-default" >
245303 < div className = "panel-heading" > { qualityHeader } </ div >
246304 < div className = "panel-body" >
247- { ! hasUnitsSelected && < p className = "text-muted" > < em > Valitse ensin päivitettävät paikat</ em > </ p > }
248- { hasUnitsSelected && renderQualityInputs ( ) }
305+ { renderQualityInputs ( ) }
249306 </ div >
250307 </ div >
251308 { ( hasUnitsSelected && hasQualitySelected ) && renderConfirmation ( ) }
@@ -266,46 +323,6 @@ const UnitMassEdit = (props) => {
266323 </ div >
267324 </ div >
268325 ) ;
269- }
270-
271- function mapStateToProps ( state , ownProps ) {
272- const { groupId, propertyId } = ownProps . params ;
273- const { unit, service } = state . data ;
274- const onlyQualityProperties = state . serviceGroup !== constants . SERVICE_GROUPS . swimming . id ;
275- const units = _ . filter ( unit , ( u ) => u . extensions . maintenance_group ) ;
276-
277- let allowedValues ;
278- let unitsIncludingSelectedProperty = [ ] ;
279- let observableProperty ;
280-
281- units . forEach ( ( u ) => {
282- const allObservableProperties = unitObservableProperties ( u , service , onlyQualityProperties ) ;
283- const selectedObservableProperty = _ . filter ( allObservableProperties , ( op ) => op . id === propertyId ) ;
284- const selectedObservablePropertyId = selectedObservableProperty [ 0 ] ?. id ;
285- if ( selectedObservablePropertyId === propertyId ) {
286- unitsIncludingSelectedProperty . push ( u ) ;
287- observableProperty = selectedObservableProperty ;
288- }
289- } ) ;
290-
291- if ( observableProperty ) {
292- allowedValues = _ . fromPairs ( _ . map ( observableProperty , ( p ) => [ p . id , allowedValuesByQuality ( p ) ] ) )
293- }
294-
295- return {
296- allowedValues,
297- groupId,
298- observableProperty : Object . assign ( { } , ...observableProperty ) ,
299- units : unitsIncludingSelectedProperty
300- } ;
301- }
302-
303- function mapDispatchToProps ( dispatch ) {
304- return {
305- enqueueObservation : ( property , allowedValue , unitId , addServicedObservation ) => {
306- dispatch ( actions . enqueueObservation ( property , allowedValue , unitId , addServicedObservation ) ) ;
307- }
308- } ;
309- }
326+ } ;
310327
311- export default withRouter ( connect ( mapStateToProps , mapDispatchToProps ) ( UnitMassEdit ) ) ;
328+ export default UnitMassEdit ;
0 commit comments