mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
fix tag issue
This commit is contained in:
parent
42b8f5372c
commit
ec69c14fb4
@ -3,7 +3,7 @@ import { Marker, Tooltip, useMap, useMapEvents } from 'react-leaflet'
|
|||||||
import { Item, LayerProps, Tag } from '../../types'
|
import { Item, LayerProps, Tag } from '../../types'
|
||||||
import MarkerIconFactory from '../../Utils/MarkerIconFactory'
|
import MarkerIconFactory from '../../Utils/MarkerIconFactory'
|
||||||
import { ItemViewPopup } from './Subcomponents/ItemViewPopup'
|
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 { useEffect, useState } from 'react'
|
||||||
import { ItemFormPopup } from './Subcomponents/ItemFormPopup'
|
import { ItemFormPopup } from './Subcomponents/ItemFormPopup'
|
||||||
import { useFilterTags, useIsLayerVisible } from './hooks/useFilter'
|
import { useFilterTags, useIsLayerVisible } from './hooks/useFilter'
|
||||||
@ -52,6 +52,8 @@ export const Layer = ({
|
|||||||
let location = useLocation();
|
let location = useLocation();
|
||||||
|
|
||||||
const allTagsLoaded = useAllTagsLoaded();
|
const allTagsLoaded = useAllTagsLoaded();
|
||||||
|
const allItemsLoaded = useAllItemsLoaded();
|
||||||
|
|
||||||
const tags = useTags();
|
const tags = useTags();
|
||||||
const addTag = useAddTag();
|
const addTag = useAddTag();
|
||||||
const [newTagsToAdd, setNewTagsToAdd] = useState<Tag[]>([]);
|
const [newTagsToAdd, setNewTagsToAdd] = useState<Tag[]>([]);
|
||||||
@ -114,17 +116,17 @@ export const Layer = ({
|
|||||||
}, [leafletRefs, location])
|
}, [leafletRefs, location])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log(`all tags loaded: ${allTagsLoaded}`);
|
||||||
}, [allTagsLoaded])
|
}, [allTagsLoaded])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(tagsReady){
|
if (tagsReady) {
|
||||||
|
const processedTags = {};
|
||||||
newTagsToAdd.map(newtag => {
|
newTagsToAdd.map(newtag => {
|
||||||
addTag(newtag);
|
if (!processedTags[newtag.name]) {
|
||||||
setNewTagsToAdd(current =>
|
processedTags[newtag.name] = true;
|
||||||
current.filter(tag => {
|
addTag(newtag);
|
||||||
return tag.name !== newtag.name;
|
}
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [tagsReady])
|
}, [tagsReady])
|
||||||
@ -139,22 +141,26 @@ export const Layer = ({
|
|||||||
filter(item => item.layer && isLayerVisible(item.layer)).
|
filter(item => item.layer && isLayerVisible(item.layer)).
|
||||||
map((item: Item) => {
|
map((item: Item) => {
|
||||||
if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
|
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] = "";
|
else item[itemTextField] = "";
|
||||||
if (item?.tags) {
|
if (item?.tags) {
|
||||||
item[itemTextField] = item[itemTextField] + '\n\n';
|
item[itemTextField] = item[itemTextField] + '\n\n';
|
||||||
item.tags.map(tag => {
|
item.tags.map(tag => {
|
||||||
if(!item[itemTextField].includes(`#${tag}`))
|
if (!item[itemTextField].includes(`#${tag}`))
|
||||||
return (item[itemTextField] = item[itemTextField] + `#${tag} `)
|
return (item[itemTextField] = item[itemTextField] + `#${tag} `)
|
||||||
return item[itemTextField]
|
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())) {
|
if (allTagsLoaded && allItemsLoaded) {
|
||||||
const newTag = {id: crypto.randomUUID(), name: tag.slice(1).toLocaleLowerCase(), color: randomColor()};
|
item[itemTextField].toLocaleLowerCase().match(hashTagRegex)?.map(tag => {
|
||||||
setNewTagsToAdd(current => [...current, newTag]);
|
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);
|
!tagsReady && setTagsReady(true);
|
||||||
|
|||||||
@ -12,13 +12,11 @@ export const TagsControl = () => {
|
|||||||
filterTags.map(tag =>
|
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 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">
|
<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><b>#{capitalizeFirstLetter(tag.name)}</b>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 * as React from "react";
|
||||||
import { Item, ItemsApi, LayerProps, Tag } from "../../../types";
|
import { Item, ItemsApi, LayerProps, Tag } from "../../../types";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
@ -23,6 +23,7 @@ const ItemContext = createContext<UseItemManagerResult>({
|
|||||||
resetItems: () => { },
|
resetItems: () => { },
|
||||||
setItemsApi: () => { },
|
setItemsApi: () => { },
|
||||||
setItemsData: () => { },
|
setItemsData: () => { },
|
||||||
|
allItemsLoaded: false
|
||||||
});
|
});
|
||||||
|
|
||||||
function useItemsManager(initialItems: Item[]): {
|
function useItemsManager(initialItems: Item[]): {
|
||||||
@ -33,10 +34,17 @@ function useItemsManager(initialItems: Item[]): {
|
|||||||
resetItems: (layer: LayerProps) => void;
|
resetItems: (layer: LayerProps) => void;
|
||||||
setItemsApi: (layer: LayerProps) => void;
|
setItemsApi: (layer: LayerProps) => void;
|
||||||
setItemsData: (layer: LayerProps) => void;
|
setItemsData: (layer: LayerProps) => void;
|
||||||
|
allItemsLoaded: boolean;
|
||||||
|
|
||||||
} {
|
} {
|
||||||
|
|
||||||
const addLayer = useAddLayer();
|
const addLayer = useAddLayer();
|
||||||
|
|
||||||
|
const [itemsCount, setItemsCount] = useState<number>(0);
|
||||||
|
const [allItemsLoaded, setallItemsLoaded] = useState<boolean>(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
|
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "ADD":
|
case "ADD":
|
||||||
@ -83,6 +91,7 @@ function useItemsManager(initialItems: Item[]): {
|
|||||||
result.map(item => {
|
result.map(item => {
|
||||||
dispatch({ type: "ADD", item: { ...item, layer: layer } });
|
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<{
|
export const ItemsProvider: React.FunctionComponent<{
|
||||||
@ -168,3 +177,8 @@ export const useSetItemsData = (): UseItemManagerResult["setItemsData"] => {
|
|||||||
const { setItemsData } = useContext(ItemContext);
|
const { setItemsData } = useContext(ItemContext);
|
||||||
return setItemsData;
|
return setItemsData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useAllItemsLoaded = (): UseItemManagerResult["allItemsLoaded"] => {
|
||||||
|
const { allItemsLoaded } = useContext(ItemContext);
|
||||||
|
return allItemsLoaded;
|
||||||
|
}
|
||||||
@ -29,17 +29,22 @@ function useTagsManager(initialTags: Tag[]): {
|
|||||||
} {
|
} {
|
||||||
|
|
||||||
const [allTagsLoaded, setallTagsLoaded] = useState<boolean>(false);
|
const [allTagsLoaded, setallTagsLoaded] = useState<boolean>(false);
|
||||||
|
const [tagCount, setTagCount] = useState<number>(0);
|
||||||
|
|
||||||
const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
|
const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "ADD":
|
case "ADD":
|
||||||
const exist = state.find((tag) =>
|
const exist = state.find((tag) =>
|
||||||
tag.id === action.tag.id ? true : false
|
tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase() ? true : false
|
||||||
);
|
);
|
||||||
if (!exist) return [
|
if (!exist) {
|
||||||
...state,
|
const newState = [
|
||||||
{ ...action.tag}
|
...state,
|
||||||
];
|
{ ...action.tag}
|
||||||
|
];
|
||||||
|
if(tagCount == newState.length) setallTagsLoaded(true);
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
else return state;
|
else return state;
|
||||||
default:
|
default:
|
||||||
throw new Error();
|
throw new Error();
|
||||||
@ -48,16 +53,20 @@ function useTagsManager(initialTags: Tag[]): {
|
|||||||
|
|
||||||
const [api, setApi] = React.useState<ItemsApi<Tag>>({} as ItemsApi<Tag>)
|
const [api, setApi] = React.useState<ItemsApi<Tag>>({} as ItemsApi<Tag>)
|
||||||
|
|
||||||
|
|
||||||
const setTagApi = useCallback(async (api: ItemsApi<Tag>) => {
|
const setTagApi = useCallback(async (api: ItemsApi<Tag>) => {
|
||||||
setApi(api);
|
setApi(api);
|
||||||
const result = await api.getItems();
|
const result = await api.getItems();
|
||||||
|
setTagCount(result.length);
|
||||||
|
if(tagCount == 0) setallTagsLoaded(true);
|
||||||
if (result) {
|
if (result) {
|
||||||
result.map(tag => {
|
result.map(tag => {
|
||||||
tag.name = tag.name.toLocaleLowerCase();
|
tag.name = tag.name.toLocaleLowerCase();
|
||||||
dispatch({ type: "ADD", tag })
|
dispatch({ type: "ADD", tag });
|
||||||
})
|
})
|
||||||
setallTagsLoaded(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const setTagData = useCallback((data: Tag[]) => {
|
const setTagData = useCallback((data: Tag[]) => {
|
||||||
@ -68,13 +77,14 @@ function useTagsManager(initialTags: Tag[]): {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const addTag = (tag: Tag) => {
|
const addTag = (tag: Tag) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: "ADD",
|
type: "ADD",
|
||||||
tag,
|
tag,
|
||||||
});
|
});
|
||||||
if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
|
if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
|
||||||
api?.createItem && api.createItem(tag);
|
api?.createItem && api.createItem(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export class Geometry {
|
|||||||
|
|
||||||
export interface Tag {
|
export interface Tag {
|
||||||
color: string;
|
color: string;
|
||||||
id: string;
|
id?: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user