Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#1972 | Name space associations
Browse files Browse the repository at this point in the history
  • Loading branch information
snyaggarwal committed Nov 28, 2024
1 parent 7e02966 commit aeab5cc
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 95 deletions.
282 changes: 193 additions & 89 deletions src/components/concepts/Associations.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import TableBody from '@mui/material/TableBody'
import TableRow from '@mui/material/TableRow'
import TableCell from '@mui/material/TableCell'
import Tooltip from '@mui/material/Tooltip'
import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
import { get, isEmpty, forEach, map, find, compact, flatten, values } from 'lodash';
import Skeleton from '@mui/material/Skeleton'
import { get, isEmpty, forEach, map, find, compact, flatten, values, filter } from 'lodash';
import ConceptIcon from './ConceptIcon'
import { generateRandomString, dropVersion } from '../../common/utils'
import { generateRandomString, dropVersion, URIToParentParams, toParentURI } from '../../common/utils'
import TagCountLabel from '../common/TagCountLabel'
import RepoChip from '../repos/RepoChip'

const groupMappings = (orderedMappings, concept, mappings, forward) => {
forEach(mappings, resource => {
Expand All @@ -23,7 +26,7 @@ const groupMappings = (orderedMappings, concept, mappings, forward) => {
if(!mapType)
mapType = forward ? 'children' : 'parent';
orderedMappings[mapType] = orderedMappings[mapType] || {order: null, direct: [], indirect: [], unknown: [], hierarchy: [], reverseHierarchy: [], self: []}
const isSelfMapping = isMapping && dropVersion(concept.url) === dropVersion(resource.cascade_target_concept_url)
const isSelfMapping = isMapping && dropVersion(concept.url) === dropVersion(resource.cascade_target_concept_url) && toParentURI(concept.url) === dropVersion(resource.cascade_target_concept_url)
let _resource = isMapping ? {...resource, isSelf: isSelfMapping, cascade_target_concept_name: resource.cascade_target_concept_name || get(find(mappings, m => dropVersion(m.url) === dropVersion(resource.cascade_target_concept_url)), 'display_name')} : {...resource, cascade_target_concept_name: resource.display_name}
if(isSelfMapping) {
if(!map(orderedMappings[mapType].self, 'id').includes(resource.id))
Expand Down Expand Up @@ -123,113 +126,214 @@ const AssociationRow = ({mappings, id, mapType, isSelf, isIndirect}) => {


const borderColor = 'rgba(0, 0, 0, 0.12)'
const Associations = ({concept, mappings, reverseMappings}) => {
const Associations = ({concept, mappings, reverseMappings, ownerMappings, reverseOwnerMappings, onLoadOwnerMappings, loadingOwnerMappings}) => {
const [orderedMappings, setOrderedMappings] = React.useState({});
const [orderedOwnerMappings, setOrderedOwnerMappings] = React.useState({});
const [ownerMappingsGroupedByRepo, setOwnerMappingsGroupedByRepo] = React.useState({});
const { t } = useTranslation()
const getMappings = () => {
let _mappings = {}
groupMappings(_mappings, concept, mappings, true)
groupMappings(_mappings, concept, reverseMappings, false)
return _mappings
}
const getOwnerMappings = () => {
let _ownerMappingsGroupedByRepo = {}
let groupedMappings = {}
forEach(ownerMappings, _mapping => {
let url = _mapping?.version_url || _mapping?.url
let parent = URIToParentParams(url)
let parentURI = toParentURI(url)
_mapping.direct = true
_mapping.parent = parent
_ownerMappingsGroupedByRepo[parentURI] ||= []
_ownerMappingsGroupedByRepo[parentURI].push(_mapping)
})
forEach(reverseOwnerMappings, _mapping => {
_mapping.indirect = true
let url = _mapping?.version_url || _mapping?.url
let parent = URIToParentParams(url)
let parentURI = toParentURI(url)
_mapping.parent = parent
_ownerMappingsGroupedByRepo[parentURI] ||= []
_ownerMappingsGroupedByRepo[parentURI].push(_mapping)
})
setOwnerMappingsGroupedByRepo(_ownerMappingsGroupedByRepo)
forEach(_ownerMappingsGroupedByRepo, (mappings, repoURI) => {
let __mappings = {}
groupMappings(__mappings, concept, filter(mappings, {direct: true}), true)
groupMappings(__mappings, concept, filter(mappings, {indirect: true}), false)
groupedMappings[repoURI] = __mappings
})
return groupedMappings
}

const count = flatten(compact(flatten(map(values(orderedMappings), mapping => values(mapping))))).length
const countOwnerMappings = ownerMappings?.length + reverseOwnerMappings?.length
const count = flatten(compact(flatten(map(values(orderedMappings), mapping => values(mapping))))).length + countOwnerMappings

React.useEffect(() => setOrderedMappings(getMappings()), [mappings, reverseMappings])
React.useEffect(() => setOrderedOwnerMappings(getOwnerMappings()), [ownerMappings, reverseOwnerMappings])

return (
<Paper className='col-xs-12 padding-0' sx={{boxShadow: 'none', border: '1px solid', borderColor: borderColor, borderRadius: '10px'}}>
<Typography component="span" sx={{borderBottom: count > 0 ? '1px solid' : '0', borderColor: borderColor, padding: '12px 16px', fontSize: '16px', color: 'surface.contrastText', display: 'flex', justifyContent: 'space-between'}}>
<Typography component="span" sx={{borderBottom: '1px solid', borderColor: borderColor, padding: '12px 16px', fontSize: '16px', color: 'surface.contrastText', display: 'flex', justifyContent: 'space-between'}}>
<TagCountLabel label={t('concept.associations')} count={count}/>
</Typography>
{
count > 0 &&
<TableContainer sx={{ maxHeight: 400, borderRadius: '10px' }}>
<Table stickyHeader size='small'>
<TableHead>
<TableRow>
<TableCell sx={{width: '10%', zIndex: 3}} className='sticky-col'><b>{t('mapping.relationship')}</b></TableCell>
<TableCell sx={{width: '20%'}}><b>{t('mapping.code')}</b></TableCell>
<TableCell sx={{width: '40%'}}><b>{t('common.name')}</b></TableCell>
<TableCell sx={{width: '20%'}}><b>{t('repo.source')}</b></TableCell>
</TableRow>
</TableHead>
<TableBody sx={{ '.MuiTableRow-root': {'&:last-child td': {border: 0, borderRadius: '10px'}} }}>
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasSelfMappings = !isEmpty(oMappings.self)
return hasSelfMappings &&
<React.Fragment key={key}>
<TableContainer sx={{ maxHeight: 400, borderRadius: '10px' }}>
<Table stickyHeader size='small'>
<TableHead>
<TableRow>
<TableCell sx={{width: '10%', zIndex: 3}} className='sticky-col'><b>{t('mapping.relationship')}</b></TableCell>
<TableCell sx={{width: '20%'}}><b>{t('mapping.code')}</b></TableCell>
<TableCell sx={{width: '40%'}}><b>{t('common.name')}</b></TableCell>
<TableCell sx={{width: '20%'}}><b>{t('repo.source')}</b></TableCell>
</TableRow>
</TableHead>
<TableBody sx={{ '.MuiTableRow-root': {'&:last-child td': {border: 0, borderRadius: '10px'}} }}>
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasSelfMappings = !isEmpty(oMappings.self)
return hasSelfMappings &&
<React.Fragment key={key}>
<AssociationRow
key={mapType}
mapType='SAME-AS'
mappings={oMappings.self}
isSelf
/>
</React.Fragment>
})
}
{
!isEmpty(orderedMappings?.children?.hierarchy) &&
<AssociationRow
mappings={orderedMappings?.children?.hierarchy}
id='has-child'
mapType='Has child'
isHierarchy
/>
}
{
!isEmpty(orderedMappings?.parent?.reverseHierarchy) &&
<AssociationRow
mappings={orderedMappings?.parent?.reverseHierarchy}
id='has-parent'
mapType='Has parent'
isHierarchy
isIndirect
/>
}
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasDirectMappings = !isEmpty(oMappings.direct)
return (
<React.Fragment key={key}>
{
hasDirectMappings &&
<AssociationRow
key={mapType}
mapType='SAME-AS'
mappings={oMappings.self}
isSelf
mapType={mapType}
mappings={oMappings.direct}
/>
</React.Fragment>
})
}
{
!isEmpty(orderedMappings?.children?.hierarchy) &&
<AssociationRow
mappings={orderedMappings?.children?.hierarchy}
id='has-child'
mapType='Has child'
isHierarchy
/>
}
{
!isEmpty(orderedMappings?.parent?.reverseHierarchy) &&
<AssociationRow
mappings={orderedMappings?.parent?.reverseHierarchy}
id='has-parent'
mapType='Has parent'
isHierarchy
isIndirect
/>
}
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasDirectMappings = !isEmpty(oMappings.direct)
return (
<React.Fragment key={key}>
{
hasDirectMappings &&
<AssociationRow
key={mapType}
mapType={mapType}
mappings={oMappings.direct}
/>
}
</React.Fragment>
)
})
}
}
</React.Fragment>
)
})
}
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasMappings = !isEmpty(oMappings.indirect)
return (
<React.Fragment key={key}>
{
hasMappings &&
<AssociationRow
key={mapType}
mappings={oMappings.indirect}
mapType={mapType}
isIndirect
/>
}
</React.Fragment>
)
})
}
<TableRow onClick={loadingOwnerMappings === null ? onLoadOwnerMappings : undefined} sx={loadingOwnerMappings === null ? {cursor: 'pointer'} : {}}>
<TableCell align='center' colSpan={4} sx={{fontSize: '12px', color: 'rgba(0, 0, 0, 0.65)'}}>
{ loadingOwnerMappings === true && <Skeleton width='100%' /> }
{ loadingOwnerMappings === false && `${t('concept.namespace_associations')} (${countOwnerMappings})` }
{
map(orderedMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasMappings = !isEmpty(oMappings.indirect)
return (
<React.Fragment key={key}>
{
hasMappings &&
<AssociationRow
key={mapType}
mappings={oMappings.indirect}
mapType={mapType}
isIndirect
/>
}
</React.Fragment>
)
})
loadingOwnerMappings === null
&&
<Button variant='text' size='small' color='primary' sx={{textTransform: 'none', padding: '0 6px', fontSize: '12px'}}>
{t('common.show')} {t('concept.namespace_associations')}
</Button>
}
</TableBody>
</Table>
</TableContainer>
}
</TableCell>
</TableRow>
{
map(orderedOwnerMappings, (gMappings, repoURI) => {
const repoMappings = ownerMappingsGroupedByRepo[repoURI]
const repo = repoMappings[0].parent
return (
<React.Fragment key={repoURI}>
<TableRow>
<TableCell align='left' colSpan={4} sx={{fontSize: '12px', padding: '6px 12px'}}>
<TagCountLabel
label={
<RepoChip sx={{paddingLeft: '12px !important'}} size='small' repo={{...repo, url: repoURI, id: repo.repo, type: repo.repoType}} />
}
count={repoMappings?.length}
/>
</TableCell>
</TableRow>
{
map(gMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasMappings = !isEmpty(oMappings.direct)
return (
<React.Fragment key={key}>
{
hasMappings &&
<AssociationRow
key={mapType}
mapType={mapType}
mappings={oMappings.direct}
/>
}
</React.Fragment>
)
})
}
{
map(gMappings, (oMappings, mapType) => {
const key = generateRandomString()
const hasMappings = !isEmpty(oMappings.indirect)
return (
<React.Fragment key={key}>
{
hasMappings &&
<AssociationRow
key={mapType}
mapType={mapType}
mappings={oMappings.indirect}
isIndirect
/>
}
</React.Fragment>
)
})
}
</React.Fragment>
)
})
}
</TableBody>
</Table>
</TableContainer>
</Paper>
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/concepts/ConceptDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ConceptProperties from './ConceptProperties'

const borderColor = 'rgba(0, 0, 0, 0.12)'

const ConceptDetails = ({ concept, repo, mappings, reverseMappings, loading }) => {
const ConceptDetails = ({ concept, repo, mappings, reverseMappings, loading, loadingOwnerMappings, ownerMappings, reverseOwnerMappings, onLoadOwnerMappings }) => {
const { t } = useTranslation()
const updatedBy = concept?.version_updated_by || concept?.updated_by
return (
Expand Down Expand Up @@ -47,7 +47,7 @@ const ConceptDetails = ({ concept, repo, mappings, reverseMappings, loading }) =
{
loading ?
<Skeleton variant="rounded" width='100%' height={120} sx={{borderRadius: '10px'}} /> :
<Associations concept={concept} mappings={mappings} reverseMappings={reverseMappings} />
<Associations concept={concept} mappings={mappings} reverseMappings={reverseMappings} ownerMappings={ownerMappings} reverseOwnerMappings={reverseOwnerMappings} onLoadOwnerMappings={onLoadOwnerMappings} loadingOwnerMappings={loadingOwnerMappings} />
}
</div>
<Typography component='span' sx={{display: 'inline-block', marginTop: '32px', padding: 0, fontSize: '12px', color: 'surface.contrastText', width: '100%'}}>
Expand Down
Loading

0 comments on commit aeab5cc

Please sign in to comment.