mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
tags url parameter
This commit is contained in:
parent
8407b92fe8
commit
b43c4f3cfb
@ -74,7 +74,8 @@ export const Layer = ({
|
||||
popupopen: (e) => {
|
||||
const item = Object.entries(leafletRefs).find(r => r[1].popup == e.popup)?.[1].item;
|
||||
if (item?.layer?.name == name && window.location.pathname.split("/")[2] != item.id) {
|
||||
window.history.pushState({}, "", `/${name}/${item.id}`)
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", `/${name}/${item.id}`+ `${params.toString() !== "" ? `?${params}` : ""}`)
|
||||
let title = "";
|
||||
if (item.name) title = item.name;
|
||||
else if (item.layer?.itemNameField) title = getValue(item, item.layer.itemNameField);
|
||||
@ -115,10 +116,6 @@ export const Layer = ({
|
||||
openPopup();
|
||||
}, [leafletRefs, location])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(`all tags loaded: ${allTagsLoaded}`);
|
||||
}, [allTagsLoaded])
|
||||
|
||||
useEffect(() => {
|
||||
if (tagsReady) {
|
||||
const processedTags = {};
|
||||
@ -143,7 +140,7 @@ export const Layer = ({
|
||||
if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
|
||||
|
||||
|
||||
if (item[itemTextField]) item[itemTextField] = getValue(item, itemTextField);
|
||||
if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField);
|
||||
else item[itemTextField] = "";
|
||||
if (item?.tags) {
|
||||
item[itemTextField] = item[itemTextField] + '\n\n';
|
||||
@ -156,7 +153,7 @@ export const Layer = ({
|
||||
}
|
||||
|
||||
|
||||
if (allTagsLoaded && allItemsLoaded) {
|
||||
if (allTagsLoaded && allItemsLoaded) {
|
||||
item[itemTextField].toLocaleLowerCase().match(hashTagRegex)?.map(tag => {
|
||||
if ((!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) && !newTagsToAdd.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
|
||||
const newTag = { id: crypto.randomUUID(), name: tag.slice(1).toLocaleLowerCase(), color: randomColor() };
|
||||
|
||||
@ -61,7 +61,9 @@ export const SearchControl = ({ clusterRef }) => {
|
||||
if (item.layer?.itemTextField) item.text = getValue(item, item.layer.itemTextField)
|
||||
return item.name?.toLowerCase().includes(value.toLowerCase()) || item.text?.toLowerCase().includes(value.toLowerCase())
|
||||
}))
|
||||
setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(value.toLowerCase())))
|
||||
let phrase = value;
|
||||
if(value.startsWith("#")) phrase = value.substring(1);
|
||||
setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(phrase.toLowerCase())))
|
||||
|
||||
}, 500, [value]);
|
||||
|
||||
@ -89,13 +91,14 @@ export const SearchControl = ({ clusterRef }) => {
|
||||
</div>
|
||||
{value.length > 0 && <button className="tw-btn tw-btn-sm tw-btn-circle tw-absolute tw-right-16 tw-top-2" onClick={() => setValue("")}>✕</button>}
|
||||
{hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 && !isGeoCoordinate(value)|| value.length == 0? "" :
|
||||
<div className='tw-card tw-card-body tw-bg-base-100 tw-p-4 tw-mt-2 tw-shadow-xl tw-overflow-scroll tw-max-h-[calc(100dvh-152px)]'>
|
||||
<div className='tw-card tw-card-body tw-bg-base-100 tw-p-4 tw-mt-2 tw-shadow-xl tw-overflow-y-auto tw-max-h-[calc(100dvh-152px)]'>
|
||||
{tagsResults.length > 0 &&
|
||||
<div className='tw-flex tw-flex-wrap tw-max-h-16 tw-overflow-hidden tw-min-h-[32px]'>
|
||||
{tagsResults.map(tag => (
|
||||
<div key={tag.name} className='tw-rounded-2xl tw-text-white tw-p-1 tw-px-4 tw-shadow-md tw-card tw-mr-2 tw-mb-2 tw-cursor-pointer' style={{ backgroundColor: tag.color }} onClick={() => {
|
||||
addFilterTag(tag)
|
||||
window.history.pushState({}, "", `/`)
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", "/" + `${params? `?${params}` : ""}`);
|
||||
}}>
|
||||
<b>#{capitalizeFirstLetter(tag.name)}</b>
|
||||
</div>
|
||||
@ -144,7 +147,7 @@ export const SearchControl = ({ clusterRef }) => {
|
||||
|
||||
<div>
|
||||
<div className='tw-text-sm tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>{geo?.properties.name ? geo?.properties.name : value}</div>
|
||||
<div className='tw-text-xs tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== "primary" && geo?.properties?.osm_value !== "path" && geo?.properties?.osm_value !== "secondary" && geo?.properties?.osm_value !== "residential" && geo?.properties?.osm_value !== "unclassified" && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}</div>
|
||||
<div className='tw-text-xs tw-overflow-hidden tw-text-ellipsis tw-whitespace-nowrap tw-max-w-[17rem]'>{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== "yes" && geo?.properties?.osm_value !== "primary" && geo?.properties?.osm_value !== "path" && geo?.properties?.osm_value !== "secondary" && geo?.properties?.osm_value !== "residential" && geo?.properties?.osm_value !== "unclassified" && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ export const TagsControl = () => {
|
||||
filterTags.map(tag =>
|
||||
<div key={tag.id} className='tw-rounded-2xl tw-text-white tw-p-2 tw-px-4 tw-shadow-xl tw-card tw-mr-2 tw-mb-2' style={{ backgroundColor: tag.color }}>
|
||||
<div className="tw-card-actions tw-justify-end">
|
||||
<label className="tw-btn tw-btn-xs tw-btn-circle tw-absolute tw--right-2 tw--top-2 tw-bg-white tw-text-gray-600" onClick={() => (removeFilterTag(tag.id!))}>✕</label>
|
||||
<label className="tw-btn tw-btn-xs tw-btn-circle tw-absolute tw--right-2 tw--top-2 tw-bg-white tw-text-gray-600" onClick={() => (removeFilterTag(tag.name!))}>✕</label>
|
||||
</div><b>#{capitalizeFirstLetter(tag.name)}</b>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -53,7 +53,8 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
}
|
||||
setLoading(false);
|
||||
map.closePopup();
|
||||
window.history.pushState({}, "", "/");
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", "/" + `${params? `?${params}` : ""}`);
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import * as React from 'react'
|
||||
import { useEffect } from 'react';
|
||||
import { ItemsApi, Tag } from '../../types';
|
||||
import { useSetTagData, useSetTagApi } from './hooks/useTags'
|
||||
import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags'
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useAddFilterTag } from './hooks/useFilter';
|
||||
|
||||
export function Tags({data, api} : {data?: Tag[], api?: ItemsApi<Tag>}) {
|
||||
const setTagData = useSetTagData();
|
||||
@ -12,6 +14,23 @@ useEffect(() => {
|
||||
api && setTagApi(api);
|
||||
}, [api, data])
|
||||
|
||||
|
||||
const location = useLocation();
|
||||
const addFilterTag = useAddFilterTag();
|
||||
const tags = useTags();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTags = params.get("tags");
|
||||
urlTags?.split(",").map(urlTag => {
|
||||
const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
|
||||
tag && addFilterTag(tag)
|
||||
});
|
||||
|
||||
}, [location, tags]);
|
||||
|
||||
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
|
||||
@ -6,19 +6,19 @@ import "./UtopiaMap.css"
|
||||
import { LatLng } from "leaflet";
|
||||
import MarkerClusterGroup from 'react-leaflet-cluster'
|
||||
import AddButton from "./Subcomponents/AddButton";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup";
|
||||
import { ItemsProvider } from "./hooks/useItems";
|
||||
import { TagsProvider } from "./hooks/useTags";
|
||||
import { TagsProvider, useAllTagsLoaded, useTags } from "./hooks/useTags";
|
||||
import { LayersProvider } from "./hooks/useLayers";
|
||||
import { FilterProvider } from "./hooks/useFilter";
|
||||
import { FilterProvider, useAddFilterTag } from "./hooks/useFilter";
|
||||
import { SearchControl } from "./Subcomponents/Controls/SearchControl";
|
||||
import { PermissionsProvider } from "./hooks/usePermissions";
|
||||
import { LeafletRefsProvider } from "./hooks/useLeafletRefs";
|
||||
import { LayerControl } from "./Subcomponents/Controls/LayerControl";
|
||||
import { QuestControl } from "./Subcomponents/Controls/QuestControl";
|
||||
import { Control } from "./Subcomponents/Controls/Control";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Outlet, useLocation } from "react-router-dom";
|
||||
import { TagsControl } from "./Subcomponents/Controls/TagsControl";
|
||||
|
||||
|
||||
@ -40,25 +40,28 @@ function UtopiaMap({
|
||||
children }
|
||||
: UtopiaMapProps) {
|
||||
|
||||
|
||||
let meta = document.getElementsByTagName('meta')
|
||||
const [metaTags, setMetaTags] = useState<HTMLCollectionOf<HTMLMetaElement>>(meta);
|
||||
|
||||
function MapEventListener(props: MapEventListenerProps) {
|
||||
useMapEvents({
|
||||
click: (e) => {
|
||||
window.history.pushState({}, "", "/");
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", `/`+ `${params.toString() !== "" ? `?${params}` : ""}`)
|
||||
document.title = document.title.split("-")[0];
|
||||
document.querySelector('meta[property="og:title"]')?.setAttribute("content", document.title);
|
||||
document.querySelector('meta[property="og:description"]')?.setAttribute("content", `${document.querySelector('meta[name="description"]')?.getAttribute("content")}`);
|
||||
|
||||
meta = metaTags;
|
||||
console.log(e.latlng.lat + ',' + e.latlng.lng);
|
||||
if (props.selectNewItemPosition != null) {
|
||||
props.setItemFormPopup({ layer: props.selectNewItemPosition, position: e.latlng })
|
||||
props.setSelectNewItemPosition(null)
|
||||
}
|
||||
},
|
||||
moveend: (e) => {
|
||||
console.log(e);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
return null
|
||||
}
|
||||
@ -68,6 +71,15 @@ function UtopiaMap({
|
||||
|
||||
const clusterRef = React.useRef();
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlPosition = params.get("position");
|
||||
|
||||
|
||||
}, [location]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -79,7 +91,7 @@ function UtopiaMap({
|
||||
<ItemsProvider initialItems={[]}>
|
||||
<LeafletRefsProvider initialLeafletRefs={{}}>
|
||||
<div className={(selectNewItemPosition != null ? "crosshair-cursor-enabled" : undefined)}>
|
||||
<MapContainer ref={mapDivRef} style={{ height: height, width: width }} center={new LatLng(center[0],center[1])} zoom={zoom} zoomControl={false}>
|
||||
<MapContainer ref={mapDivRef} style={{ height: height, width: width }} center={new LatLng(center[0], center[1])} zoom={zoom} zoomControl={false}>
|
||||
<Control position='topLeft' zIndex="1000">
|
||||
<SearchControl clusterRef={clusterRef} />
|
||||
<TagsControl />
|
||||
|
||||
@ -2,10 +2,11 @@ import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import * as React from "react";
|
||||
import { LayerProps, Tag } from "../../../types";
|
||||
import { useLayers } from "./useLayers";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD_TAG"; tag: Tag }
|
||||
| { type: "REMOVE_TAG"; id: string }
|
||||
| { type: "REMOVE_TAG"; name: string }
|
||||
| { type: "RESET_TAGS" }
|
||||
| { type: "TOGGLE_LAYER"; layer: LayerProps }
|
||||
| { type: "ADD_LAYER"; layer: LayerProps }
|
||||
@ -33,7 +34,7 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
searchPhrase: string;
|
||||
visibleLayers: LayerProps[];
|
||||
addFilterTag: (tag: Tag) => void;
|
||||
removeFilterTag: (id: string) => void;
|
||||
removeFilterTag: (name: string) => void;
|
||||
resetFilterTags: () => void;
|
||||
setSearchPhrase: (phrase: string) => void;
|
||||
addVisibleLayer: (layer: LayerProps) => void;
|
||||
@ -53,7 +54,7 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
];
|
||||
else return state;
|
||||
case "REMOVE_TAG":
|
||||
return state.filter(({ id }) => id !== action.id);
|
||||
return state.filter(({ name }) => name !== action.name);
|
||||
case "RESET_TAGS":
|
||||
return initialTags;
|
||||
default:
|
||||
@ -89,6 +90,13 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
const [searchPhrase, searchPhraseSet] = React.useState<string>("");
|
||||
|
||||
const addFilterTag = (tag: Tag) => {
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
let urlTags = params.get("tags");
|
||||
if(!urlTags?.includes(tag.name))
|
||||
params.set("tags", `${urlTags ? urlTags : ""}${urlTags? ',' : ''}${tag.name}`)
|
||||
window.history.pushState('','', "?" +params.toString());
|
||||
|
||||
dispatchTags({
|
||||
type: "ADD_TAG",
|
||||
tag,
|
||||
@ -96,10 +104,29 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
|
||||
};
|
||||
|
||||
const removeFilterTag = useCallback((id: string) => {
|
||||
const removeFilterTag = useCallback((name: string) => {
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
let urlTags = params.get("tags");
|
||||
let newUrlTags = "";
|
||||
let tags = urlTags?.split(",");
|
||||
if(tags?.length==0 && urlTags?.length && urlTags?.length > 0) tags[0]=urlTags;
|
||||
tags?.map(urlTag => {
|
||||
if(!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase()))
|
||||
newUrlTags = newUrlTags + `${newUrlTags===""? urlTag : `,${urlTag}`}`
|
||||
});
|
||||
if(newUrlTags !== "") {
|
||||
params.set("tags", `${newUrlTags}`)
|
||||
window.history.pushState('','', "?" +params.toString());
|
||||
}
|
||||
else {
|
||||
|
||||
window.history.pushState('','', window.location.pathname);
|
||||
}
|
||||
|
||||
dispatchTags({
|
||||
type: "REMOVE_TAG",
|
||||
id,
|
||||
name,
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user