fix tag issue

This commit is contained in:
Anton Tranelis 2024-02-02 19:26:05 +01:00
parent 42b8f5372c
commit ec69c14fb4
5 changed files with 71 additions and 43 deletions

View File

@ -3,7 +3,7 @@ import { Marker, Tooltip, useMap, useMapEvents } from 'react-leaflet'
import { Item, LayerProps, Tag } from '../../types'
import MarkerIconFactory from '../../Utils/MarkerIconFactory'
import { ItemViewPopup } from './Subcomponents/ItemViewPopup'
import { useItems, useSetItemsApi, useSetItemsData } from './hooks/useItems'
import { useAllItemsLoaded, useItems, useSetItemsApi, useSetItemsData } from './hooks/useItems'
import { useEffect, useState } from 'react'
import { ItemFormPopup } from './Subcomponents/ItemFormPopup'
import { useFilterTags, useIsLayerVisible } from './hooks/useFilter'
@ -52,6 +52,8 @@ export const Layer = ({
let location = useLocation();
const allTagsLoaded = useAllTagsLoaded();
const allItemsLoaded = useAllItemsLoaded();
const tags = useTags();
const addTag = useAddTag();
const [newTagsToAdd, setNewTagsToAdd] = useState<Tag[]>([]);
@ -114,17 +116,17 @@ export const Layer = ({
}, [leafletRefs, location])
useEffect(() => {
console.log(`all tags loaded: ${allTagsLoaded}`);
}, [allTagsLoaded])
useEffect(() => {
if(tagsReady){
if (tagsReady) {
const processedTags = {};
newTagsToAdd.map(newtag => {
addTag(newtag);
setNewTagsToAdd(current =>
current.filter(tag => {
return tag.name !== newtag.name;
}),
)
if (!processedTags[newtag.name]) {
processedTags[newtag.name] = true;
addTag(newtag);
}
})
}
}, [tagsReady])
@ -137,32 +139,36 @@ export const Layer = ({
filter(item =>
filterTags.length == 0 ? item : filterTags.every(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))?.
filter(item => item.layer && isLayerVisible(item.layer)).
map((item: Item) => {
map((item: Item) => {
if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
if(item[itemTextField]) item[itemTextField] = getValue(item, itemTextField);
if (item[itemTextField]) item[itemTextField] = getValue(item, itemTextField);
else item[itemTextField] = "";
if (item?.tags) {
item[itemTextField] = item[itemTextField] + '\n\n';
item.tags.map(tag => {
if(!item[itemTextField].includes(`#${tag}`))
return (item[itemTextField] = item[itemTextField] + `#${tag} `)
if (!item[itemTextField].includes(`#${tag}`))
return (item[itemTextField] = item[itemTextField] + `#${tag} `)
return item[itemTextField]
});
}
if(allTagsLoaded) {
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()};
setNewTagsToAdd(current => [...current, newTag]);
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 = { name: tag.slice(1).toLocaleLowerCase(), color: randomColor() };
setNewTagsToAdd(current => [...current, newTag]);
}
});
!tagsReady && setTagsReady(true);
}
}
const itemTtags = getItemTags(item);
const latitude = itemLatitudeField && item ? getValue(item, itemLatitudeField) : undefined;
const longitude = itemLongitudeField && item ? getValue(item, itemLongitudeField) : undefined;

View File

@ -12,13 +12,11 @@ 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.id!))}></label>
</div><b>#{capitalizeFirstLetter(tag.name)}</b>
</div>
)
}
</div>)
}

View File

@ -1,4 +1,4 @@
import { useCallback, useReducer, createContext, useContext, useEffect } from "react";
import { useCallback, useReducer, createContext, useContext, useEffect, useState } from "react";
import * as React from "react";
import { Item, ItemsApi, LayerProps, Tag } from "../../../types";
import { toast } from "react-toastify";
@ -23,6 +23,7 @@ const ItemContext = createContext<UseItemManagerResult>({
resetItems: () => { },
setItemsApi: () => { },
setItemsData: () => { },
allItemsLoaded: false
});
function useItemsManager(initialItems: Item[]): {
@ -33,10 +34,17 @@ function useItemsManager(initialItems: Item[]): {
resetItems: (layer: LayerProps) => void;
setItemsApi: (layer: LayerProps) => void;
setItemsData: (layer: LayerProps) => void;
allItemsLoaded: boolean;
} {
const addLayer = useAddLayer();
const [itemsCount, setItemsCount] = useState<number>(0);
const [allItemsLoaded, setallItemsLoaded] = useState<boolean>(false);
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
switch (action.type) {
case "ADD":
@ -83,6 +91,7 @@ function useItemsManager(initialItems: Item[]): {
result.map(item => {
dispatch({ type: "ADD", item: { ...item, layer: layer } });
})
setallItemsLoaded(true);
}
}, [])
@ -123,7 +132,7 @@ function useItemsManager(initialItems: Item[]): {
return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData };
return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData, allItemsLoaded };
}
export const ItemsProvider: React.FunctionComponent<{
@ -167,4 +176,9 @@ export const useSetItemsApi = (): UseItemManagerResult["setItemsApi"] => {
export const useSetItemsData = (): UseItemManagerResult["setItemsData"] => {
const { setItemsData } = useContext(ItemContext);
return setItemsData;
};
};
export const useAllItemsLoaded = (): UseItemManagerResult["allItemsLoaded"] => {
const { allItemsLoaded } = useContext(ItemContext);
return allItemsLoaded;
}

View File

@ -29,17 +29,22 @@ function useTagsManager(initialTags: Tag[]): {
} {
const [allTagsLoaded, setallTagsLoaded] = useState<boolean>(false);
const [tagCount, setTagCount] = useState<number>(0);
const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
switch (action.type) {
case "ADD":
const exist = state.find((tag) =>
tag.id === action.tag.id ? true : false
tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase() ? true : false
);
if (!exist) return [
...state,
{ ...action.tag}
];
if (!exist) {
const newState = [
...state,
{ ...action.tag}
];
if(tagCount == newState.length) setallTagsLoaded(true);
return newState;
}
else return state;
default:
throw new Error();
@ -48,16 +53,20 @@ function useTagsManager(initialTags: Tag[]): {
const [api, setApi] = React.useState<ItemsApi<Tag>>({} as ItemsApi<Tag>)
const setTagApi = useCallback(async (api: ItemsApi<Tag>) => {
setApi(api);
const result = await api.getItems();
setTagCount(result.length);
if(tagCount == 0) setallTagsLoaded(true);
if (result) {
result.map(tag => {
tag.name = tag.name.toLocaleLowerCase();
dispatch({ type: "ADD", tag })
dispatch({ type: "ADD", tag });
})
setallTagsLoaded(true);
}
}, [])
const setTagData = useCallback((data: Tag[]) => {
@ -67,14 +76,15 @@ function useTagsManager(initialTags: Tag[]): {
})
}, []);
const addTag = (tag: Tag) => {
dispatch({
type: "ADD",
tag,
});
if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
api?.createItem && api.createItem(tag);
}
const addTag = (tag: Tag) => {
dispatch({
type: "ADD",
tag,
});
if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
api?.createItem && api.createItem(tag);
}
};

View File

@ -69,7 +69,7 @@ export class Geometry {
export interface Tag {
color: string;
id: string;
id?: string;
name: string;
}