mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
filter map on tag-click
This commit is contained in:
parent
c32b7b8f51
commit
289ea16340
9
package-lock.json
generated
9
package-lock.json
generated
@ -15,6 +15,7 @@
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-toastify": "^9.1.3",
|
||||
"tributejs": "^5.1.3",
|
||||
"tw-elements": "^1.0.0-beta2"
|
||||
@ -3837,6 +3838,14 @@
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-string-replace": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.1.tgz",
|
||||
"integrity": "sha512-26TUbLzLfHQ5jO5N7y3Mx88eeKo0Ml0UjCQuX4BMfOd/JX+enQqlKpL1CZnmjeBRvQE8TR+ds9j1rqx9CxhKHQ==",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify": {
|
||||
"version": "9.1.3",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-leaflet-cluster": "^2.1.0",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-toastify": "^9.1.3",
|
||||
"tributejs": "^5.1.3",
|
||||
"tw-elements": "^1.0.0-beta2"
|
||||
|
||||
@ -39,8 +39,6 @@ export const Layer = (props: LayerProps) => {
|
||||
items.filter(item => item.layer?.name === props.name)?.filter(item =>
|
||||
filterTags.length == 0 ? item : item.tags?.some(tag => filterTags.some(filterTag => filterTag.id === tag.id)))?.map((place: Item) => {
|
||||
const tags = place.tags;
|
||||
if(place.name === "docutopia")
|
||||
console.log(tags);
|
||||
|
||||
let color1 = "#666";
|
||||
let color2 = "RGBA(35, 31, 32, 0.2)";
|
||||
|
||||
@ -6,7 +6,7 @@ import { useAddItem, useUpdateItem } from '../hooks/useItems'
|
||||
import { Geometry, LayerProps, Item, ItemsApi } from '../../../types'
|
||||
import { TextAreaInput } from '../../Input/TextAreaInput'
|
||||
import { TextInput } from '../../Input/TextInput'
|
||||
import { hashTagRegex } from '../../../Utils/HeighlightTags'
|
||||
import { hashTagRegex } from '../../../Utils/HashTagRegex'
|
||||
import { useAddTag } from '../hooks/useTags'
|
||||
import { randomColor } from '../../../Utils/RandomColor'
|
||||
|
||||
|
||||
@ -2,13 +2,39 @@ import * as React from 'react'
|
||||
import { Item } from '../../../../types'
|
||||
import { useTags } from '../../hooks/useTags';
|
||||
import { replaceURLs } from '../../../../Utils/ReplaceURLs';
|
||||
import { heighlightTags } from '../../../../Utils/HeighlightTags';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
import { useAddFilterTag, useResetFilterTags } from '../../hooks/useFilter';
|
||||
import { hashTagRegex } from '../../../../Utils/HashTagRegex';
|
||||
|
||||
export const TextView = ({item} : {item?: Item}) => {
|
||||
const all_tags = useTags();
|
||||
const tags = useTags();
|
||||
|
||||
const addFilterTag = useAddFilterTag();
|
||||
const resetFilterTags = useResetFilterTags();
|
||||
|
||||
|
||||
return(
|
||||
<>
|
||||
{
|
||||
reactStringReplace(item?.text, hashTagRegex, (match, i) => (
|
||||
<>
|
||||
{
|
||||
|
||||
tags.filter(t => t.id.toLowerCase() == match.slice(1).toLowerCase()).map(tag =>
|
||||
<a style={{color: tag.color, fontWeight: 'bold', cursor: 'pointer'}} key={tag.id+i+item?.id} onClick={()=>{
|
||||
resetFilterTags();
|
||||
addFilterTag(tag);
|
||||
}}>#{tag.id}</a>
|
||||
|
||||
return (
|
||||
<p style={{ whiteSpace: "pre-wrap" }} className="!tw-m-0 !tw-mb-2" dangerouslySetInnerHTML={{ __html: replaceURLs(heighlightTags(item && item.text ? item.text:"", all_tags)) }} />
|
||||
|
||||
)
|
||||
}
|
||||
</>
|
||||
))
|
||||
}
|
||||
</>
|
||||
)
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -4,7 +4,8 @@ import {Tag} from "../../../types";
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD"; tag: Tag }
|
||||
| { type: "REMOVE"; id: string };
|
||||
| { type: "REMOVE"; id: string }
|
||||
| { type: "RESET"};
|
||||
|
||||
type UseFilterManagerResult = ReturnType<typeof useFilterManager>;
|
||||
|
||||
@ -12,13 +13,14 @@ const FilterContext = createContext<UseFilterManagerResult>({
|
||||
filterTags: [],
|
||||
addFilterTag: () => { },
|
||||
removeFilterTag: () => { },
|
||||
|
||||
resetFilterTags: () => { },
|
||||
});
|
||||
|
||||
function useFilterManager(initialTags: Tag[]): {
|
||||
filterTags: Tag[];
|
||||
addFilterTag: (tag: Tag) => void;
|
||||
removeFilterTag: (id: string) => void;
|
||||
resetFilterTags: () => void;
|
||||
} {
|
||||
const [filterTags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
@ -31,9 +33,10 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
action.tag,
|
||||
];
|
||||
else return state;
|
||||
|
||||
case "REMOVE":
|
||||
return state.filter(({ id }) => id !== action.id);
|
||||
case "RESET":
|
||||
return initialTags;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
@ -56,8 +59,14 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetFilterTags = useCallback(() => {
|
||||
dispatch({
|
||||
type: "RESET",
|
||||
});
|
||||
}, []);
|
||||
|
||||
return { filterTags, addFilterTag, removeFilterTag };
|
||||
|
||||
return { filterTags, addFilterTag, removeFilterTag, resetFilterTags };
|
||||
}
|
||||
|
||||
export const FilterProvider: React.FunctionComponent<{
|
||||
@ -82,3 +91,8 @@ export const useRemoveFilterTag = (): UseFilterManagerResult["removeFilterTag"]
|
||||
const { removeFilterTag } = useContext(FilterContext);
|
||||
return removeFilterTag;
|
||||
};
|
||||
|
||||
export const useResetFilterTags = (): UseFilterManagerResult["resetFilterTags"] => {
|
||||
const { resetFilterTags } = useContext(FilterContext);
|
||||
return resetFilterTags;
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import { Item, ItemsApi, LayerProps, Tag } from "../../../types";
|
||||
import { toast } from "react-toastify";
|
||||
import { useAddLayer } from "./useLayers";
|
||||
import { useTags } from "./useTags";
|
||||
import { hashTagRegex } from "../../../Utils/HeighlightTags";
|
||||
import { hashTagRegex } from "../../../Utils/HashTagRegex";
|
||||
|
||||
|
||||
type ActionType =
|
||||
|
||||
1
src/Utils/HashTagRegex.tsx
Normal file
1
src/Utils/HashTagRegex.tsx
Normal file
@ -0,0 +1 @@
|
||||
export const hashTagRegex = /(#+[a-zA-Z0-9A-Za-zÀ-ÖØ-öø-ʸ(_)]{1,})/g;
|
||||
@ -1,14 +0,0 @@
|
||||
import { Tag } from "../types";
|
||||
|
||||
export const hashTagRegex = /(#+[a-zA-Z0-9A-Za-zÀ-ÖØ-öø-ʸ(_)]{1,})/g;
|
||||
|
||||
export function heighlightTags(message: string, tags: Tag[]): string {
|
||||
if (!message) return "";
|
||||
|
||||
message = message.replace(hashTagRegex, function (string) {
|
||||
const tag = tags.find(t => t.id.toLowerCase() == string.slice(1).toLowerCase())
|
||||
return `<span style="background-color: ${tag ? tag.color : '#aaa' };padding: 0px 5px;border-radius: 7px;cursor: pointer;color:#fff">` + string + '</span>'
|
||||
});
|
||||
|
||||
return message;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user