Skip to content

Commit

Permalink
fix: serviceTreeView fix indeterminate checkbox state PL-17
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkojamG committed Nov 20, 2024
1 parent 6117779 commit c2c2f53
Showing 1 changed file with 28 additions and 38 deletions.
66 changes: 28 additions & 38 deletions src/views/ServiceTreeView/ServiceTreeView.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { css } from '@emotion/css';
/* eslint-disable react/forbid-prop-types */
import styled from '@emotion/styled';
import { Search } from '@mui/icons-material';
import { Checkbox, List, Typography } from '@mui/material';
import { useTheme } from '@mui/styles';
import { List, Typography } from '@mui/material';
import PropTypes from 'prop-types';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Checkbox as HDSCheckbox } from 'hds-react';
import { visuallyHidden } from '@mui/utils';
import config from '../../../config';
import { SMAccordion, SMButton, TitleBar } from '../../components';
import { setMobilityTree } from '../../redux/actions/mobilityTree';
Expand Down Expand Up @@ -44,7 +45,7 @@ const getVariantDependentVariables = (variant, serviceTreeServices, mobilityTree
};
};

const ServiceTreeView = ({ intl, variant }) => {
function ServiceTreeView({ intl, variant }) {
const navigator = useSelector(selectNavigator);
const citySettings = useSelector(selectSelectedCities);
const organizationSettings = useSelector(selectSelectedOrganizations);
Expand All @@ -61,7 +62,6 @@ const ServiceTreeView = ({ intl, variant }) => {
const dispatch = useDispatch();
const getLocaleText = useLocaleText();
const isMobile = useMobileStatus();
const theme = useTheme();
const {
serviceApi,
titleKey,
Expand All @@ -88,7 +88,7 @@ const ServiceTreeView = ({ intl, variant }) => {
const nodeObjects = node.children.map(child => services.find(e => e.id === child));
nodes.push(...nodeObjects);
// Check if any child nodes are opened to repeat this function on them
nodeObjects.forEach((obj) => {
nodeObjects.forEach(obj => {
if (obj?.id && opened.some(item => item === obj.id)) {
nodes.push(...checkChildNodes(obj));
}
Expand All @@ -108,7 +108,9 @@ const ServiceTreeView = ({ intl, variant }) => {
const fetchNodeCounts = async (nodes, fullSearch) => {
const idList = nodes.map(node => node.id);
// Do not fetch unit counts again for nodes that have the data, unless specified by fullSearch
const filteredIdList = fullSearch ? idList : idList.filter(id => !unitCounts.some(count => count.id === id))
const filteredIdList = fullSearch ? idList : idList
.filter(id => !unitCounts.some(count => count.id === id));

const smAPI = new ServiceMapAPI();
const fetchOptions = {};
if (organizationSettings.length) {
Expand All @@ -119,17 +121,17 @@ const ServiceTreeView = ({ intl, variant }) => {
fetchOptions.municipality = citySettings;
}
const counts = await Promise.all(
filteredIdList.map(async (id) => {
filteredIdList.map(async id => {
const count = await smAPI.serviceNodeSearch(variant, id, fetchOptions, true);
return { id, count };
}),
);
if (fullSearch) {
setUnitCounts(counts)
setUnitCounts(counts);
} else {
setUnitCounts([...unitCounts, ...counts])
setUnitCounts([...unitCounts, ...counts]);
}
}
};

const setInitialServices = () => {
// Fetch initially shown service nodes when first entering the pag
Expand All @@ -142,11 +144,11 @@ const ServiceTreeView = ({ intl, variant }) => {
});
};

const fetchChildServices = async (service) => {
const fetchChildServices = async service => {
// Fetch and set to state the child nodes of the opened node
fetch(`${serviceApi}?parent=${service}&page=1&page_size=1000`)
.then(response => response.json())
.then((data) => {
.then(data => {
setServices([...services, ...data.results]);
if (variant === SERVICE_TREE) {
fetchNodeCounts(data.results);
Expand Down Expand Up @@ -183,13 +185,12 @@ const ServiceTreeView = ({ intl, variant }) => {
}
if (child?.children) {
data.push(...child.children);
child.children.forEach((c) => {
child.children.forEach(c => {
getSelectedChildNodes(c, data);
});
} return data;
};


const handleExpand = (service, isOpen) => {
if (isOpen) { // Close expanded item
setOpened(opened.filter(e => e !== service.id));
Expand All @@ -215,7 +216,7 @@ const ServiceTreeView = ({ intl, variant }) => {
setSelected(selected.filter(element => element.id !== item.id));
}

// If checbox is not checked, add checkbox selections
// If checbox is not checked, add checkbox selections
} else {
// Select all visible child nodes as well
let newState = [item, ...checkChildNodes(item)];
Expand Down Expand Up @@ -280,13 +281,15 @@ const ServiceTreeView = ({ intl, variant }) => {
if (!services.length) {
setInitialServices();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (variant === SERVICE_TREE) {
setUnitCounts([]);
fetchNodeCounts(services, true);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [citySettings, organizationSettings]);

function calculateTitle(item) {
Expand All @@ -295,7 +298,7 @@ const ServiceTreeView = ({ intl, variant }) => {
}

// Calculate count
const countItem = unitCounts.find(countItem => countItem.id === item.id)
const countItem = unitCounts.find(countItem => countItem.id === item.id);
return `${getLocaleText(item.name)} ${countItem !== null && countItem !== undefined ? `(${countItem.count})` : ''}`;
}

Expand All @@ -314,10 +317,6 @@ const ServiceTreeView = ({ intl, variant }) => {
const childIsSelected = checkChildNodes(item)
.some(node => selected.some(item => item.id === node.id));

const checkBoxFocusClass = css({
boxShadow: `inset 0 0 0 4px ${theme.palette.primary.main} !important`,
});

return (
<li key={item.id}>
<StyledAccordion
Expand All @@ -331,14 +330,14 @@ const ServiceTreeView = ({ intl, variant }) => {
{level > 0 && (drawOuterLines(level, last, item.id))}
<StyledCheckBox>
{drawCheckboxLines(isOpen, level, item.id)}
<Checkbox
focusVisibleClassName={checkBoxFocusClass}
inputProps={{ title: checkboxSrTitle }}
onClick={e => handleCheckboxClick(e, item)}
icon={<StyledCheckBoxIcon />}
color="primary"
<HDSCheckbox
id={item.id}
name={item.id}
label={<Typography component="span" style={visuallyHidden}>{checkboxSrTitle}</Typography>}
checked={isSelected}
indeterminate={childIsSelected && !isSelected}
onChange={e => handleCheckboxClick(e, item)}
style={{ '--size': '1rem' }}
/>
</StyledCheckBox>
</>
Expand Down Expand Up @@ -381,7 +380,7 @@ const ServiceTreeView = ({ intl, variant }) => {

// If node's parent is also checked, add only parent to list of selected nodes for search
const selectedList = [];
selected.forEach((e) => {
selected.forEach(e => {
if (!selected.some(i => i.id === e.parent)) {
selectedList.push(e);
}
Expand Down Expand Up @@ -421,7 +420,7 @@ const ServiceTreeView = ({ intl, variant }) => {
</StyledFloatingDiv>
</StyledFlexContainer>
);
};
}

const StyledFlexContainer = styled.div(() => ({
display: 'flex',
Expand Down Expand Up @@ -474,15 +473,6 @@ const StyledGuidanceInfoText = styled(Typography)(({ theme }) => ({
textAlign: 'left',
}));

const StyledCheckBoxIcon = styled('span')(() => ({
margin: -1,
width: 15,
height: 15,
backgroundColor: '#fff',
border: '1px solid #323232;',
borderRadius: 1,
}));

const StyledCheckBox = styled('div')(() => ({
width: 40,
height: '100%',
Expand Down

0 comments on commit c2c2f53

Please sign in to comment.