Skip to content

Commit 1b91047

Browse files
committed
OpenConceptLab/ocl_issues#2190 | Proposed | autofilling attributes from input row values | Showing on top
1 parent 779087a commit 1b91047

3 files changed

Lines changed: 124 additions & 16 deletions

File tree

src/components/map-projects/MapProject.jsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,6 @@ const MapProject = () => {
297297
setColumns(cols)
298298
}
299299

300-
const updateRow = (index, columnKey, newValue) => setData(prevData => map(prevData, row => (row.__index === index ? {...row, [`${columnKey}__updated`]: newValue} : row)))
301-
302300
const resetState = () => {
303301
setRowStatuses({reviewed: [], readyForReview: [], unmapped: []})
304302
setDecisions({})
@@ -962,7 +960,7 @@ const MapProject = () => {
962960

963961
const getConcept = concept => concept?.url ? conceptCache[concept.url] || concept : concept
964962

965-
const onProposedUpdate = event => setProposed(prev => ({...prev, [rowIndex]: {...(prev[rowIndex] || {}), [event.target.id]: event.target.value}}))
963+
const onProposedUpdate = proposedState => setProposed(prev => ({...prev, [rowIndex]: {...proposedState}}))
966964

967965
const onCandidatesOrderChange = (property, order) => {
968966
setCandidatesOrderBy(property)
@@ -1250,8 +1248,6 @@ const MapProject = () => {
12501248
labelDisplayedRows,
12511249
},
12521250
}}
1253-
disableRowSelectionOnClick
1254-
onCellEditStop={(params, event) => updateRow(params.id, params.field, params?.reason === "enterKeyDown" ? event?.target?.value : event?.target?.value || params.value || '')}
12551251
columnVisibilityModel={columnVisibilityModel}
12561252
onColumnVisibilityModelChange={setColumnVisibilityModel}
12571253
/>
@@ -1367,6 +1363,7 @@ const MapProject = () => {
13671363
mapTypes={mapTypes}
13681364
allMapTypes={allMapTypes}
13691365
onMap={onMap}
1366+
proposed={proposed[rowIndex]}
13701367
/>
13711368
<Divider sx={{width: '100%'}} />
13721369
<DecisionSelector
@@ -1417,7 +1414,14 @@ const MapProject = () => {
14171414
<Propose
14181415
onChange={onProposedUpdate}
14191416
proposed={proposed[rowIndex]}
1420-
onSubmit={event => onDecisionChange(event, 'propose')}
1417+
onSubmit={(event, state) => {
1418+
if(state)
1419+
setProposed(prev => ({...prev, [rowIndex]: {...state}}))
1420+
onDecisionChange(event, 'propose')
1421+
}}
1422+
repo={repoVersion || repo}
1423+
row={row}
1424+
columns={columns}
14211425
/>
14221426
}
14231427
{

src/components/map-projects/MappingDecisionResult.jsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,22 @@ import Typography from '@mui/material/Typography'
33
import ListItemText from '@mui/material/ListItemText'
44
import has from 'lodash/has'
55
import values from 'lodash/values'
6+
import isEmpty from 'lodash/isEmpty'
7+
import find from 'lodash/find'
68
import compact from 'lodash/compact'
79
import MapButton from './MapButton'
810
import { URIToParentParams } from '../../common/utils'
911
import Score from './Score'
1012

11-
const MappingDecisionResult = ({targetConcept, row, rowIndex, mapTypes, allMapTypes, onMap}) => {
13+
const MappingDecisionResult = ({targetConcept, row, rowIndex, mapTypes, allMapTypes, onMap, proposed}) => {
1214
const parentParams = targetConcept?.url ? URIToParentParams(targetConcept.url) : {}
1315
const hasClass = has(row, 'Class') || has(row, 'Concept Class')
1416
const hasDatatype = has(row, 'Datatype') || has(row, 'datatype')
17+
const getFieldFromProposed = field => {
18+
return find(proposed?.attributes, attr => attr?.name?.toLowerCase()?.includes(field))?.value || ''
19+
}
20+
21+
1522
return (
1623
<div className='col-xs-12 padding-0' style={{display: 'flex', margin: '8px 0', justifyContent: 'space-between'}}>
1724
<div style={{maxWidth: '45%'}}>
@@ -61,6 +68,31 @@ const MappingDecisionResult = ({targetConcept, row, rowIndex, mapTypes, allMapTy
6168
</div>
6269
</>
6370
}
71+
{
72+
!targetConcept?.url && !isEmpty(proposed) &&
73+
<>
74+
<div style={{marginLeft: '8px'}}>
75+
<Typography component='div' sx={{color: 'rgba(0, 0, 0, 0.6)', fontSize: '12px'}}>Relationship</Typography>
76+
<Typography component='div' sx={{}}>{proposed?.map_type || '-'}</Typography>
77+
</div>
78+
<div style={{marginLeft: '24px', maxWidth: '45%'}}>
79+
<Typography component='span' sx={{color: 'rgba(0, 0, 0, 0.6)', fontSize: '12px'}}>Target Code</Typography>
80+
<div className='col-xs-12 padding-0'>
81+
<ListItemText
82+
className='searchable'
83+
primary={`${proposed?.source || ''}:${proposed?.id || ''} ${proposed?.name || ''}`}
84+
secondary={
85+
<span className='searchable' style={{fontSize: '12px'}}>
86+
Class: <i>{getFieldFromProposed('class')}</i>,
87+
Datatype: <i>{getFieldFromProposed('datatype')}</i>
88+
</span>
89+
}
90+
sx={{marginTop: 0, '.MuiListItemText-secondary': {marginTop: '-4px'}}}
91+
/>
92+
</div>
93+
</div>
94+
</>
95+
}
6496
</div>
6597

6698
)

src/components/map-projects/Propose.jsx

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,97 @@
11
import React from 'react'
22
import times from 'lodash/times'
33
import get from 'lodash/get'
4+
import { find, forEach} from 'lodash'
45
import TextField from '@mui/material/TextField'
56
import Typography from '@mui/material/Typography'
67
import Button from '@mui/material/Button'
78

8-
const Propose = ({onChange, proposed, onSubmit}) => {
9+
const Propose = ({onChange, proposed, onSubmit, repo, row, columns}) => {
910
const [attributes, setAttributes] = React.useState(1)
11+
const repoLabel = `${repo?.short_code || repo?.id}:${repo?.version || repo.id}`
12+
13+
const getStateFromRow = () => {
14+
let _state = {id: '', name: '', attributes: []}
15+
forEach(row, (value, key) => {
16+
if(!key.startsWith('__')) {
17+
const col = find(columns, {dataKey: key})
18+
if(col?.label) {
19+
if(['id', 'name'].includes(col.label.toLowerCase()))
20+
_state[col.label.toLowerCase()] = value
21+
else
22+
_state.attributes.push({name: col.label, value: value})
23+
} else {
24+
_state.attributes.push({name: key, value: value})
25+
}
26+
}
27+
})
28+
return _state
29+
}
30+
31+
const [state, setState] = React.useState({})
32+
33+
const _onChange = event => {
34+
event.persist()
35+
let newState;
36+
if(event.target.id.includes('attributes.')) {
37+
const idParts = event.target.id.split('.')
38+
const attributeIndex = parseInt(idParts[1])
39+
const attributeType = idParts[2]
40+
const newAttributes = [...state.attributes]
41+
newAttributes[attributeIndex][attributeType] = event.target.value
42+
newState = {...state, attributes: newAttributes}
43+
console.log(newState)
44+
setState(newState)
45+
} else {
46+
newState = {...state, [event.target.id]: event.target.value}
47+
setState(newState)
48+
}
49+
onChange(newState)
50+
}
51+
52+
React.useEffect(() => {
53+
const stateFromRow = getStateFromRow()
54+
let _attributes = proposed?.attributes?.length ? [...proposed.attributes] || [] : [...stateFromRow.attributes] || []
55+
let _proposed = {...proposed}
56+
_proposed.attributes = [...(proposed.attributes || [])]
57+
forEach(_proposed, (value, key) => {
58+
if(key.includes('attributes.')) {
59+
let parts = key.split('.')
60+
_proposed.attributes[parseInt(parts[1])][parts[2]] = value
61+
delete _proposed[key]
62+
}
63+
})
64+
setState({
65+
..._proposed,
66+
source: proposed?.source || repoLabel || '',
67+
id: proposed?.id || stateFromRow?.id || '',
68+
name: proposed?.name || stateFromRow?.name || '',
69+
attributes: _attributes,
70+
map_type: proposed?.map_type || 'SAME-AS',
71+
note: proposed?.note || ''
72+
})
73+
setAttributes(_attributes?.length && _attributes.length > 0 ? _attributes.length : 1)
74+
}, [row])
75+
76+
const _onSubmit = event => {
77+
event.persist()
78+
onSubmit(event, state)
79+
}
80+
1081
return (
1182
<div className='col-xs-12 padding-0' style={{margin: '12px 0'}}>
1283
<div className='col-xs-12 padding-0'>
13-
<TextField id='source' sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Target Source' value={proposed?.source || ''} onChange={onChange}/>
14-
<TextField id='id' sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Concept ID' value={proposed?.id || ''} onChange={onChange}/>
15-
<TextField id='name' sx={{width: 'calc(50% - 12px)', margin: '4px 6px',}} label='Name' value={proposed?.name || ''} onChange={onChange}/>
84+
<TextField id='source' sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Target Source' value={state.source} onChange={_onChange}/>
85+
<TextField id='id' sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Concept ID' value={state?.id || ''} onChange={_onChange}/>
86+
<TextField id='name' sx={{width: 'calc(50% - 12px)', margin: '4px 6px',}} label='Name' value={state?.name || ''} onChange={_onChange}/>
87+
<TextField id='map_type' sx={{width: 'calc(50% - 12px)', margin: '4px 6px',}} label='Map Type' value={state?.map_type || 'SAME-AS'} onChange={_onChange}/>
1688
<Typography sx={{fontWeight: 'bold', margin: '10px 10px 4px'}}>Attributes</Typography>
1789
{
1890
times(attributes, i => {
1991
return (
2092
<div className='col-xs-12 padding-0' key={i}>
21-
<TextField id={`attributes.${i}.name`} sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Attribute Name' value={get(proposed, `attributes.${i}.name`) || ''} onChange={onChange}/>
22-
<TextField id={`attributes.${i}.value`} sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Attribute Value' value={get(proposed, `attributes.${i}.value`) || ''} onChange={onChange}/>
93+
<TextField id={`attributes.${i}.name`} sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Attribute Name' value={get(state, `attributes.${i}.name`) || ''} onChange={_onChange}/>
94+
<TextField id={`attributes.${i}.value`} sx={{width: 'calc(50% - 12px)', margin: '4px 6px'}} label='Attribute Value' value={get(state, `attributes.${i}.value`) || ''} onChange={_onChange}/>
2395
</div>
2496
)
2597
})
@@ -35,12 +107,12 @@ const Propose = ({onChange, proposed, onSubmit}) => {
35107
label="Proposal note"
36108
multiline
37109
rows={5}
38-
value={proposed?.note || ''}
39-
onChange={onChange}
110+
value={state?.note || ''}
111+
onChange={_onChange}
40112
/>
41113
</div>
42114
<div className='col-xs-12 padding-0' style={{margin: '16px 0', display: 'flex', alignItems: 'center'}}>
43-
<Button color='primary' onClick={onSubmit} variant='contained' sx={{textTransform: 'none'}}>
115+
<Button color='primary' onClick={_onSubmit} variant='contained' sx={{textTransform: 'none'}}>
44116
Propose
45117
</Button>
46118
</div>

0 commit comments

Comments
 (0)