<commit_before>import { ChevronDown } from '@datapunt/asc-assets'
import {
  Checkbox,
  Icon,
  Label,
  Paragraph,
  styles,
  themeColor,
  themeSpacing,
} from '@datapunt/asc-ui'
import { useMatomo } from '@datapunt/matomo-tracker-react'
import queryString from 'querystring'
import React, { useEffect, useMemo, useState } from 'react'
import { useSelector } from 'react-redux'
import styled, { css } from 'styled-components'
import LoginLink from '../../../app/components/Links/LoginLink/LoginLink'
import { isPrintOrEmbedMode } from '../../../shared/ducks/ui/ui'
import MAP_CONFIG from '../../services/map.config'

const isAuthorised = (layer, user) =>
  !layer.authScope || (user.authenticated && user.scopes.includes(layer.authScope))

const isInsideZoomLevel = (layer, zoomLevel) =>
  zoomLevel >= layer.minZoom && zoomLevel <= layer.maxZoom

const TitleWrapper = styled.div`
  display: flex;
`
const StyledLabel = styled(Label)`
  width: 100%;
`

const CollectionLabel = styled(StyledLabel)`
  font-weight: 700;
`

const StyledCheckbox = styled(Checkbox)`
  padding: 0px;
  padding-right: ${themeSpacing(2)};
`

const NonSelectableLegendParagraph = styled(Paragraph)`
  margin-bottom: ${themeSpacing(2)};
`

// We cannot use a button because of IE11
const LayerButton = styled.div.attrs({
  role: 'button',
})`
  display: flex;
  cursor: pointer;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 0 12px;
  background-color: ${themeColor('tint', 'level2')};

  & > ${styles.IconStyle} {
    margin-right: 3px;
    transition: transform 0.2s ease-in-out;
    ${({ isOpen }) =>
      isOpen &&
      css`
        transform: rotate(180deg);
      `}
  }
`

const constructLegendIconUrl = (mapLayer, legendItem) => {
  if (legendItem.iconUrl) {
    return legendItem.iconUrl
  }

  return [
    MAP_CONFIG.OVERLAY_ROOT,
    `${mapLayer.url || legendItem.url}?`,
    `version=${MAP_CONFIG.VERSION_NUMBER}&`,
    'service=WMS&',
    'request=GetLegendGraphic&',
    `sld_version=${MAP_CONFIG.SLD_VERSION}&`,
    `layer=${
      (legendItem.layers && legendItem.layers[0]) || (mapLayer.layers && mapLayer.layers[0])
    }&`,
    'format=image/svg%2Bxml&',
    legendItem.params ? `${queryString.stringify(legendItem.params)}&` : '',
    `rule=${encodeURIComponent(legendItem.imageRule || legendItem.title)}`,
  ].join('')
}

const MapLegend = ({
  activeMapLayers,
  onLayerVisibilityToggle,
  user,
  zoomLevel,
  printMode,
  onLayerToggle,
  title,
  overlays,
}) => {
  const ref = React.createRef()
  const { trackEvent } = useMatomo()
  const isPrintOrEmbedView = useSelector(isPrintOrEmbedMode)

  // Todo: This need to be refactored on redux level, so MapLayers and LegendItems will get a isVisible option there.
  const mapLayers = useMemo(
    () =>
      activeMapLayers.map((mapLayer) => ({
        ...mapLayer,
        legendItems: [
          ...(mapLayer.legendItems?.map((legendItem) => ({
            ...legendItem,
            isVisible: overlays.some(
              (overlay) =>
                (overlay.id === legendItem.id && overlay.isVisible) || legendItem.notSelectable,
            ),
          })) || []),
        ],
        isVisible: overlays.some((overlay) =>
          [{ id: mapLayer.id }, ...(mapLayer.legendItems || [])].some(
            (legendItem) => overlay.id === legendItem.id && overlay.isVisible,
          ),
        ),
        isEmbedded: overlays.some((overlay) =>
          [{ id: mapLayer.id }, ...(mapLayer.legendItems || [])].some(
            (legendItem) => overlay.id === legendItem.id && isPrintOrEmbedView,
          ),
        ),
      })),
    [overlays, activeMapLayers],
  )

  const [isOpen, setOpen] = useState(isPrintOrEmbedView ?? false)

  const allInvisible = mapLayers.every(({ isVisible }) => !isVisible)
  const collectionIndeterminate =
    mapLayers.some(
      ({ isVisible, legendItems }) =>
        !isVisible || legendItems.some(({ isVisible: legendVisibility }) => !legendVisibility),
    ) && !allInvisible

  const handleLayerToggle = (checked, mapLayer) => {
    onLayerToggle(mapLayer)

    // Only track the event when the mapLayer gets checked
    if (checked) {
      // Sanitize the collection title to use it as action
      const action = mapLayer.title.toLowerCase().replace(/[: ][ ]*/g, '_')

      // eslint-disable-next-line no-unused-expressions
      mapLayer?.legendItems?.forEach(({ title: legendItemTitle }) =>
        trackEvent({
          category: 'kaartlaag',
          action,
          name: legendItemTitle,
        }),
      )
    }
  }

  useEffect(() => {
    if (isOpen && ref.current) {
      ref.current.scrollIntoView({
        behavior: 'smooth',
        block: 'start',
      })
    }
  }, [ref.current, isOpen])

  // Check if some of the maplayers are opened on first render
  const hasOpenMapLayers = useMemo(
    () =>
      mapLayers.some(
        ({ isVisible, legendItems }) =>
          isVisible === true ||
          (isVisible === true &&
            legendItems.some(({ isVisible: legendItemIsVisible }) => legendItemIsVisible === true)), // legenditems could be visible in another MapLegend
      ),
    [mapLayers],
  )

  // Open the maplegend if some of the maplayers are opened
  useEffect(() => {
    if (hasOpenMapLayers) setOpen(true)
  }, [hasOpenMapLayers])

  const handleOnChangeCollection = (e) => {
    // We want to check all the layers when user clicks on an indeterminate checkbox
    if (!e.currentTarget.checked && collectionIndeterminate) {
      mapLayers
        .filter(({ isVisible }) => !isVisible)
        .forEach((mapLayer) => {
          handleLayerToggle(e.currentTarget.checked, mapLayer)
        })

      mapLayers.forEach((mapLayer) => {
        // eslint-disable-next-line no-unused-expressions
        mapLayer.legendItems?.length > 0
          ? mapLayer.legendItems
              .filter(({ isVisible }) => !isVisible)
              .forEach((legendItem) => onLayerVisibilityToggle(legendItem.id, false))
          : null
      })
      setOpen(true)
    } else {
      activeMapLayers.forEach((mapLayer) => {
        handleLayerToggle(e.currentTarget.checked, mapLayer)
      })
      setOpen(e.currentTarget.checked)
    }
  }

  return (
    <>
      {(!isPrintOrEmbedView ||
        (isPrintOrEmbedView && mapLayers.some(({ isEmbedded }) => isEmbedded))) && ( // Also display the collection title when maplayer is embedded
        <LayerButton ref={ref} onClick={() => setOpen(!isOpen)} isOpen={isOpen}>
          <TitleWrapper>
            <CollectionLabel key={title} htmlFor={title} label={title}>
              {!isPrintOrEmbedView ? (
                <StyledCheckbox
                  id={title}
                  className="checkbox"
                  name={title}
                  indeterminate={collectionIndeterminate}
                  checked={!allInvisible}
                  onChange={handleOnChangeCollection}
                />
              ) : null}
            </CollectionLabel>
          </TitleWrapper>
          <Icon size={15}>
            <ChevronDown />
          </Icon>
        </LayerButton>
      )}
      {isOpen && (
        <ul className="map-legend">
          {mapLayers &&
            mapLayers
              .filter(({ isEmbedded }) => (isPrintOrEmbedView ? isEmbedded : true)) // Only include the embedded layers when in certain views
              .map((mapLayer, mapLayerIndex) => {
                const layerIsChecked = mapLayer.isVisible
                const layerIsIndeterminate =
                  mapLayer.legendItems.some(({ isVisible }) => !isVisible) && layerIsChecked

                const hasLegendItems = mapLayer.legendItems.length > 0

                return (
                  <li
                    className="map-legend__map-layer"
                    // eslint-disable-next-line react/no-array-index-key
                    key={mapLayerIndex}
                  >
                    <div
                      className={`
                    map-legend__category
                    map-legend__category--${
                      !hasLegendItems &&
                      mapLayer.legendItems.some((legendItem) => legendItem.notSelectable)
                        ? 'un'
                        : ''
                    }selectable-legend
                  `}
                    >
                      <StyledLabel key={mapLayer.id} htmlFor={mapLayer.id} label={mapLayer.title}>
                        <>
                          {!hasLegendItems ? (
                            <div
                              className={`
                            map-legend__image
                            map-legend__image--selectable
                          `}
                            >
                              <img
                                alt={mapLayer.title}
                                src={constructLegendIconUrl(mapLayer, mapLayer)}
                              />
                            </div>
                          ) : null}
                          <StyledCheckbox
                            id={mapLayer.id}
                            className="checkbox"
                            variant="tertiary"
                            checked={layerIsChecked}
                            indeterminate={layerIsIndeterminate}
                            name={mapLayer.title}
                            onChange={
                              /* istanbul ignore next */
                              (e) => {
                                // Sometimes we dont want the active maplayers to be deleted from the query parameters in the url
                                if (isPrintOrEmbedView || layerIsIndeterminate) {
                                  return mapLayer.legendItems.length > 0 &&
                                    mapLayer.legendItems.some(({ id }) => id !== null)
                                    ? mapLayer.legendItems
                                        .filter(({ isVisible }) =>
                                          layerIsIndeterminate ? !isVisible : true,
                                        )
                                        .forEach(({ id }) => {
                                          onLayerVisibilityToggle(
                                            id,
                                            layerIsIndeterminate ? false : !e.currentTarget.checked,
                                          )
                                        })
                                    : onLayerVisibilityToggle(mapLayer.id, !e.currentTarget.checked)
                                }
                                return handleLayerToggle(e.currentTarget.checked, mapLayer)
                              }
                            }
                          />
                        </>
                      </StyledLabel>
                    </div>
                    {!isAuthorised(mapLayer, user) && (
                      <div className="map-legend__notification">
                        <span>
                          <LoginLink variant="blank">Zichtbaar na inloggen</LoginLink>
                        </span>
                      </div>
                    )}
                    {isAuthorised(mapLayer, user) && !isInsideZoomLevel(mapLayer, zoomLevel) && (
                      <div className="map-legend__notification">
                        <span>
                          {`Zichtbaar bij verder ${
                            zoomLevel < mapLayer.minZoom ? 'inzoomen' : 'uitzoomen'
                          }`}
                        </span>
                      </div>
                    )}
                    {isAuthorised(mapLayer, user) &&
                      layerIsChecked &&
                      isInsideZoomLevel(mapLayer, zoomLevel) &&
                      !mapLayer.disabled && (
                        <ul className="map-legend__items">
                          {hasLegendItems
                            ? mapLayer.legendItems.map((legendItem, legendItemIndex) => {
                                const legendItemIsVisible = legendItem.isVisible
                                const LegendLabel = !legendItem.notSelectable
                                  ? StyledLabel
                                  : NonSelectableLegendParagraph
                                return !legendItemIsVisible && printMode ? null : (
                                  <li
                                    className="map-legend__item"
                                    // eslint-disable-next-line react/no-array-index-key
                                    key={legendItemIndex}
                                  >
                                    <LegendLabel
                                      key={legendItem.id}
                                      htmlFor={legendItem.id}
                                      label={legendItem.title}
                                    >
                                      <div
                                        className={`
                            map-legend__image
                            map-legend__image--${
                              legendItem.notSelectable ? 'not-selectable' : 'selectable'
                            }
                          `}
                                      >
                                        <img
                                          alt={legendItem.title}
                                          src={constructLegendIconUrl(mapLayer, legendItem)}
                                        />
                                      </div>
                                      {!legendItem.notSelectable ? (
                                        <StyledCheckbox
                                          id={legendItem.id}
                                          className="checkbox"
                                          variant="tertiary"
                                          checked={legendItemIsVisible}
                                          name={legendItem.title}
                                          onChange={
                                            /* istanbul ignore next */
                                            () =>
                                              onLayerVisibilityToggle(
                                                legendItem.id,
                                                legendItemIsVisible,
                                              )
                                          }
                                        />
                                      ) : (
                                        legendItem.title
                                      )}
                                    </LegendLabel>
                                  </li>
                                )
                              })
                            : null}
                        </ul>
                      )}
                  </li>
                )
              })}
        </ul>
      )}
    </>
  )
}

export default MapLegend
<commit_msg>Track map layers without legend items when enabled<commit_after>import { ChevronDown } from '@datapunt/asc-assets'
import {
  Checkbox,
  Icon,
  Label,
  Paragraph,
  styles,
  themeColor,
  themeSpacing,
} from '@datapunt/asc-ui'
import { useMatomo } from '@datapunt/matomo-tracker-react'
import queryString from 'querystring'
import React, { useEffect, useMemo, useState } from 'react'
import { useSelector } from 'react-redux'
import styled, { css } from 'styled-components'
import LoginLink from '../../../app/components/Links/LoginLink/LoginLink'
import { isPrintOrEmbedMode } from '../../../shared/ducks/ui/ui'
import MAP_CONFIG from '../../services/map.config'

const isAuthorised = (layer, user) =>
  !layer.authScope || (user.authenticated && user.scopes.includes(layer.authScope))

const isInsideZoomLevel = (layer, zoomLevel) =>
  zoomLevel >= layer.minZoom && zoomLevel <= layer.maxZoom

const TitleWrapper = styled.div`
  display: flex;
`
const StyledLabel = styled(Label)`
  width: 100%;
`

const CollectionLabel = styled(StyledLabel)`
  font-weight: 700;
`

const StyledCheckbox = styled(Checkbox)`
  padding: 0px;
  padding-right: ${themeSpacing(2)};
`

const NonSelectableLegendParagraph = styled(Paragraph)`
  margin-bottom: ${themeSpacing(2)};
`

// We cannot use a button because of IE11
const LayerButton = styled.div.attrs({
  role: 'button',
})`
  display: flex;
  cursor: pointer;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 0 12px;
  background-color: ${themeColor('tint', 'level2')};

  & > ${styles.IconStyle} {
    margin-right: 3px;
    transition: transform 0.2s ease-in-out;
    ${({ isOpen }) =>
      isOpen &&
      css`
        transform: rotate(180deg);
      `}
  }
`

const constructLegendIconUrl = (mapLayer, legendItem) => {
  if (legendItem.iconUrl) {
    return legendItem.iconUrl
  }

  return [
    MAP_CONFIG.OVERLAY_ROOT,
    `${mapLayer.url || legendItem.url}?`,
    `version=${MAP_CONFIG.VERSION_NUMBER}&`,
    'service=WMS&',
    'request=GetLegendGraphic&',
    `sld_version=${MAP_CONFIG.SLD_VERSION}&`,
    `layer=${
      (legendItem.layers && legendItem.layers[0]) || (mapLayer.layers && mapLayer.layers[0])
    }&`,
    'format=image/svg%2Bxml&',
    legendItem.params ? `${queryString.stringify(legendItem.params)}&` : '',
    `rule=${encodeURIComponent(legendItem.imageRule || legendItem.title)}`,
  ].join('')
}

const MapLegend = ({
  activeMapLayers,
  onLayerVisibilityToggle,
  user,
  zoomLevel,
  printMode,
  onLayerToggle,
  title,
  overlays,
}) => {
  const ref = React.createRef()
  const { trackEvent } = useMatomo()
  const isPrintOrEmbedView = useSelector(isPrintOrEmbedMode)

  function trackLayerEnabled(mapLayer) {
    // Sanitize the collection title to use it as action
    const action = mapLayer.title.toLowerCase().replace(/[: ][ ]*/g, '_')

    if (!mapLayer.legendItems || mapLayer.legendItems.length === 0) {
      trackEvent({
        category: 'kaartlaag',
        action,
        name: mapLayer.title,
      })
    } else {
      mapLayer.legendItems.forEach(({ title: legendItemTitle }) =>
        trackEvent({
          category: 'kaartlaag',
          action,
          name: legendItemTitle,
        }),
      )
    }
  }

  // Todo: This need to be refactored on redux level, so MapLayers and LegendItems will get a isVisible option there.
  const mapLayers = useMemo(
    () =>
      activeMapLayers.map((mapLayer) => ({
        ...mapLayer,
        legendItems: [
          ...(mapLayer.legendItems?.map((legendItem) => ({
            ...legendItem,
            isVisible: overlays.some(
              (overlay) =>
                (overlay.id === legendItem.id && overlay.isVisible) || legendItem.notSelectable,
            ),
          })) || []),
        ],
        isVisible: overlays.some((overlay) =>
          [{ id: mapLayer.id }, ...(mapLayer.legendItems || [])].some(
            (legendItem) => overlay.id === legendItem.id && overlay.isVisible,
          ),
        ),
        isEmbedded: overlays.some((overlay) =>
          [{ id: mapLayer.id }, ...(mapLayer.legendItems || [])].some(
            (legendItem) => overlay.id === legendItem.id && isPrintOrEmbedView,
          ),
        ),
      })),
    [overlays, activeMapLayers],
  )

  const [isOpen, setOpen] = useState(isPrintOrEmbedView ?? false)

  const allInvisible = mapLayers.every(({ isVisible }) => !isVisible)
  const collectionIndeterminate =
    mapLayers.some(
      ({ isVisible, legendItems }) =>
        !isVisible || legendItems.some(({ isVisible: legendVisibility }) => !legendVisibility),
    ) && !allInvisible

  const handleLayerToggle = (checked, mapLayer) => {
    onLayerToggle(mapLayer)

    // Only track the event when the mapLayer gets checked
    if (checked) {
      trackLayerEnabled(mapLayer)
    }
  }

  useEffect(() => {
    if (isOpen && ref.current) {
      ref.current.scrollIntoView({
        behavior: 'smooth',
        block: 'start',
      })
    }
  }, [ref.current, isOpen])

  // Check if some of the maplayers are opened on first render
  const hasOpenMapLayers = useMemo(
    () =>
      mapLayers.some(
        ({ isVisible, legendItems }) =>
          isVisible === true ||
          (isVisible === true &&
            legendItems.some(({ isVisible: legendItemIsVisible }) => legendItemIsVisible === true)), // legenditems could be visible in another MapLegend
      ),
    [mapLayers],
  )

  // Open the maplegend if some of the maplayers are opened
  useEffect(() => {
    if (hasOpenMapLayers) setOpen(true)
  }, [hasOpenMapLayers])

  const handleOnChangeCollection = (e) => {
    // We want to check all the layers when user clicks on an indeterminate checkbox
    if (!e.currentTarget.checked && collectionIndeterminate) {
      mapLayers
        .filter(({ isVisible }) => !isVisible)
        .forEach((mapLayer) => {
          handleLayerToggle(e.currentTarget.checked, mapLayer)
        })

      mapLayers.forEach((mapLayer) => {
        // eslint-disable-next-line no-unused-expressions
        mapLayer.legendItems?.length > 0
          ? mapLayer.legendItems
              .filter(({ isVisible }) => !isVisible)
              .forEach((legendItem) => onLayerVisibilityToggle(legendItem.id, false))
          : null
      })
      setOpen(true)
    } else {
      activeMapLayers.forEach((mapLayer) => {
        handleLayerToggle(e.currentTarget.checked, mapLayer)
      })
      setOpen(e.currentTarget.checked)
    }
  }

  return (
    <>
      {(!isPrintOrEmbedView ||
        (isPrintOrEmbedView && mapLayers.some(({ isEmbedded }) => isEmbedded))) && ( // Also display the collection title when maplayer is embedded
        <LayerButton ref={ref} onClick={() => setOpen(!isOpen)} isOpen={isOpen}>
          <TitleWrapper>
            <CollectionLabel key={title} htmlFor={title} label={title}>
              {!isPrintOrEmbedView ? (
                <StyledCheckbox
                  id={title}
                  className="checkbox"
                  name={title}
                  indeterminate={collectionIndeterminate}
                  checked={!allInvisible}
                  onChange={handleOnChangeCollection}
                />
              ) : null}
            </CollectionLabel>
          </TitleWrapper>
          <Icon size={15}>
            <ChevronDown />
          </Icon>
        </LayerButton>
      )}
      {isOpen && (
        <ul className="map-legend">
          {mapLayers &&
            mapLayers
              .filter(({ isEmbedded }) => (isPrintOrEmbedView ? isEmbedded : true)) // Only include the embedded layers when in certain views
              .map((mapLayer, mapLayerIndex) => {
                const layerIsChecked = mapLayer.isVisible
                const layerIsIndeterminate =
                  mapLayer.legendItems.some(({ isVisible }) => !isVisible) && layerIsChecked

                const hasLegendItems = mapLayer.legendItems.length > 0

                return (
                  <li
                    className="map-legend__map-layer"
                    // eslint-disable-next-line react/no-array-index-key
                    key={mapLayerIndex}
                  >
                    <div
                      className={`
                    map-legend__category
                    map-legend__category--${
                      !hasLegendItems &&
                      mapLayer.legendItems.some((legendItem) => legendItem.notSelectable)
                        ? 'un'
                        : ''
                    }selectable-legend
                  `}
                    >
                      <StyledLabel key={mapLayer.id} htmlFor={mapLayer.id} label={mapLayer.title}>
                        <>
                          {!hasLegendItems ? (
                            <div
                              className={`
                            map-legend__image
                            map-legend__image--selectable
                          `}
                            >
                              <img
                                alt={mapLayer.title}
                                src={constructLegendIconUrl(mapLayer, mapLayer)}
                              />
                            </div>
                          ) : null}
                          <StyledCheckbox
                            id={mapLayer.id}
                            className="checkbox"
                            variant="tertiary"
                            checked={layerIsChecked}
                            indeterminate={layerIsIndeterminate}
                            name={mapLayer.title}
                            onChange={
                              /* istanbul ignore next */
                              (e) => {
                                // Sometimes we dont want the active maplayers to be deleted from the query parameters in the url
                                if (isPrintOrEmbedView || layerIsIndeterminate) {
                                  return mapLayer.legendItems.length > 0 &&
                                    mapLayer.legendItems.some(({ id }) => id !== null)
                                    ? mapLayer.legendItems
                                        .filter(({ isVisible }) =>
                                          layerIsIndeterminate ? !isVisible : true,
                                        )
                                        .forEach(({ id }) => {
                                          onLayerVisibilityToggle(
                                            id,
                                            layerIsIndeterminate ? false : !e.currentTarget.checked,
                                          )
                                        })
                                    : onLayerVisibilityToggle(mapLayer.id, !e.currentTarget.checked)
                                }
                                return handleLayerToggle(e.currentTarget.checked, mapLayer)
                              }
                            }
                          />
                        </>
                      </StyledLabel>
                    </div>
                    {!isAuthorised(mapLayer, user) && (
                      <div className="map-legend__notification">
                        <span>
                          <LoginLink variant="blank">Zichtbaar na inloggen</LoginLink>
                        </span>
                      </div>
                    )}
                    {isAuthorised(mapLayer, user) && !isInsideZoomLevel(mapLayer, zoomLevel) && (
                      <div className="map-legend__notification">
                        <span>
                          {`Zichtbaar bij verder ${
                            zoomLevel < mapLayer.minZoom ? 'inzoomen' : 'uitzoomen'
                          }`}
                        </span>
                      </div>
                    )}
                    {isAuthorised(mapLayer, user) &&
                      layerIsChecked &&
                      isInsideZoomLevel(mapLayer, zoomLevel) &&
                      !mapLayer.disabled && (
                        <ul className="map-legend__items">
                          {hasLegendItems
                            ? mapLayer.legendItems.map((legendItem, legendItemIndex) => {
                                const legendItemIsVisible = legendItem.isVisible
                                const LegendLabel = !legendItem.notSelectable
                                  ? StyledLabel
                                  : NonSelectableLegendParagraph
                                return !legendItemIsVisible && printMode ? null : (
                                  <li
                                    className="map-legend__item"
                                    // eslint-disable-next-line react/no-array-index-key
                                    key={legendItemIndex}
                                  >
                                    <LegendLabel
                                      key={legendItem.id}
                                      htmlFor={legendItem.id}
                                      label={legendItem.title}
                                    >
                                      <div
                                        className={`
                            map-legend__image
                            map-legend__image--${
                              legendItem.notSelectable ? 'not-selectable' : 'selectable'
                            }
                          `}
                                      >
                                        <img
                                          alt={legendItem.title}
                                          src={constructLegendIconUrl(mapLayer, legendItem)}
                                        />
                                      </div>
                                      {!legendItem.notSelectable ? (
                                        <StyledCheckbox
                                          id={legendItem.id}
                                          className="checkbox"
                                          variant="tertiary"
                                          checked={legendItemIsVisible}
                                          name={legendItem.title}
                                          onChange={
                                            /* istanbul ignore next */
                                            () =>
                                              onLayerVisibilityToggle(
                                                legendItem.id,
                                                legendItemIsVisible,
                                              )
                                          }
                                        />
                                      ) : (
                                        legendItem.title
                                      )}
                                    </LegendLabel>
                                  </li>
                                )
                              })
                            : null}
                        </ul>
                      )}
                  </li>
                )
              })}
        </ul>
      )}
    </>
  )
}

export default MapLegend

{'fraction_non_alphanumeric': 0.1032507283857662, 'fraction_numerical': 0.0021278685304612563, 'mean_word_length': 1.1723794623808848, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 189, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 150, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3385965', 'n_tokens_mistral': 7618, 'n_tokens_neox': 7134, 'n_words': 1343}