url layer parameter

This commit is contained in:
Anton Tranelis 2025-05-22 12:40:02 +02:00
parent a6bb7dd7cb
commit baafaa43b1
3 changed files with 87 additions and 33 deletions

View File

@ -42,36 +42,5 @@ export function Tags({ data, api }: { data?: Tag[]; api?: ItemsApi<Tag> }) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [api, data])
const location = useLocation()
const addFilterTag = useAddFilterTag()
const resetFilterTags = useResetFilterTags()
const tags = useTags()
const filterTags = useFilterTags()
useEffect(() => {
const params = new URLSearchParams(location.search)
const urlTags = params.get('tags')
const decodedTags = urlTags ? decodeURIComponent(urlTags) : ''
const decodedTagsArray = decodedTags.split(';')
if (
decodedTagsArray.some(
(ut) => !filterTags.find((ft) => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase()),
) ||
filterTags.some(
(ft) =>
!decodedTagsArray.find((ut) => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase()),
)
) {
resetFilterTags()
decodedTagsArray.map((urlTag) => {
const tag = tags.find((t) => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
tag && addFilterTag(tag)
return null
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location, tags])
return <></>
}

View File

@ -17,7 +17,15 @@ import { useTheme } from '#components/AppShell/hooks/useTheme'
import { containsUUID } from '#utils/ContainsUUID'
import { useClusterRef, useSetClusterRef } from './hooks/useClusterRef'
import { useAddVisibleLayer } from './hooks/useFilter'
import {
useAddFilterTag,
useAddVisibleLayer,
useFilterTags,
useResetFilterTags,
useResetVisibleLayers,
useToggleVisibleLayer,
useVisibleLayer,
} from './hooks/useFilter'
import { useLayers } from './hooks/useLayers'
import { useLeafletRefs } from './hooks/useLeafletRefs'
import {
@ -25,6 +33,7 @@ import {
useSetMapClicked,
useSetSelectPosition,
} from './hooks/useSelectPosition'
import { useTags } from './hooks/useTags'
import AddButton from './Subcomponents/AddButton'
import { Control } from './Subcomponents/Controls/Control'
import { FilterControl } from './Subcomponents/Controls/FilterControl'
@ -200,6 +209,60 @@ export function UtopiaMapInner({
}
}
const addFilterTag = useAddFilterTag()
const resetFilterTags = useResetFilterTags()
const tags = useTags()
const filterTags = useFilterTags()
useEffect(() => {
const params = new URLSearchParams(location.search)
const urlTags = params.get('tags')
const decodedTags = urlTags ? decodeURIComponent(urlTags) : ''
const decodedTagsArray = decodedTags.split(';').filter(Boolean)
const urlDiffersFromState =
decodedTagsArray.some(
(ut) => !filterTags.find((ft) => ut.toLowerCase() === ft.name.toLowerCase()),
) ||
filterTags.some(
(ft) => !decodedTagsArray.find((ut) => ut.toLowerCase() === ft.name.toLowerCase()),
)
if (urlDiffersFromState) {
resetFilterTags()
decodedTagsArray.forEach((urlTag) => {
const match = tags.find((t) => t.name.toLowerCase() === urlTag.toLowerCase())
if (match) addFilterTag(match)
})
}
}, [location, tags, filterTags, addFilterTag, resetFilterTags])
const toggleVisibleLayer = useToggleVisibleLayer()
const allLayers = useLayers()
const initializedRef = useRef(false)
useEffect(() => {
if (initializedRef.current || allLayers.length === 0) return
const params = new URLSearchParams(location.search)
const urlLayersParam = params.get('layers')
if (!urlLayersParam) return
const urlLayerNames = urlLayersParam.split(',').filter(Boolean)
const layerNamesToHide = allLayers
.map((l) => l.name)
.filter((name) => !urlLayerNames.includes(name))
layerNamesToHide.forEach((name) => {
const match = allLayers.find((l) => l.name === name)
if (match) toggleVisibleLayer(match)
})
initializedRef.current = true
}, [location, allLayers, toggleVisibleLayer])
return (
<div className={`tw:h-full ${selectNewItemPosition != null ? 'crosshair-cursor-enabled' : ''}`}>
<Outlet />

View File

@ -4,7 +4,7 @@
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable no-case-declarations */
import { useCallback, useReducer, createContext, useContext, useState } from 'react'
import { useCallback, useReducer, createContext, useContext, useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useLayers } from './useLayers'
@ -100,6 +100,28 @@ function useFilterManager(initialTags: Tag[]): {
}
}, initialLayers)
const allLayers = useLayers()
useEffect(() => {
if (allLayers.length === 0) return
const visibleNames = visibleLayers.map((l) => l.name)
const allNames = allLayers.map((l) => l.name)
const params = new URLSearchParams(location.search)
const allVisible =
visibleNames.length === allNames.length &&
visibleNames.every((name) => allNames.includes(name))
if (allVisible) {
params.delete('layers')
} else {
params.set('layers', visibleNames.join(','))
}
navigate(`${location.pathname}?${params.toString()}`, { replace: true })
}, [visibleLayers, allLayers, navigate])
const [visibleGroupTypes, dispatchGroupTypes] = useReducer(
(state: string[], action: ActionType) => {
switch (action.type) {