mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
optimization for profile layers
This commit is contained in:
parent
5b01dc983d
commit
07492564d7
@ -1,11 +1,17 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Item } from '../../types'
|
import { Item } from '../../types'
|
||||||
import * as PropTypes from 'prop-types'
|
import * as PropTypes from 'prop-types'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
|
|
||||||
export const ItemForm = ({ children, item }: { children?: React.ReactNode, item?: Item }) => {
|
export const ItemForm = ({ children, item, title, setPopupTitle }: { children?: React.ReactNode, item?: Item, title?: string, setPopupTitle?: React.Dispatch<React.SetStateAction<string>> }) => {
|
||||||
|
useEffect(() => {
|
||||||
|
setPopupTitle&& title && setPopupTitle(title);
|
||||||
|
|
||||||
|
}, [title])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>{
|
<div className='tw-flex tw-justify-center'>{
|
||||||
children ?
|
children ?
|
||||||
React.Children.toArray(children).map((child) =>
|
React.Children.toArray(children).map((child) =>
|
||||||
React.isValidElement<{ item: Item, test: string }>(child) ?
|
React.isValidElement<{ item: Item, test: string }>(child) ?
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export const Layer = ({
|
|||||||
itemOwnerField,
|
itemOwnerField,
|
||||||
itemLatitudeField = 'position.coordinates.1',
|
itemLatitudeField = 'position.coordinates.1',
|
||||||
itemLongitudeField = 'position.coordinates.0',
|
itemLongitudeField = 'position.coordinates.0',
|
||||||
|
onlyOnePerOwner = false,
|
||||||
setItemFormPopup,
|
setItemFormPopup,
|
||||||
itemFormPopup,
|
itemFormPopup,
|
||||||
clusterRef
|
clusterRef
|
||||||
@ -63,8 +64,8 @@ export const Layer = ({
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemNameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, setItemFormPopup, itemFormPopup, clusterRef });
|
data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemNameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, onlyOnePerOwner, setItemFormPopup, itemFormPopup, clusterRef });
|
||||||
api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemNameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, setItemFormPopup, itemFormPopup, clusterRef });
|
api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemNameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, onlyOnePerOwner, setItemFormPopup, itemFormPopup, clusterRef });
|
||||||
}, [data, api])
|
}, [data, api])
|
||||||
|
|
||||||
useMapEvents({
|
useMapEvents({
|
||||||
@ -138,8 +139,9 @@ 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)) {
|
||||||
|
item[itemTextField] = getValue(item, itemTextField);
|
||||||
if (item?.tags) {
|
if (item?.tags) {
|
||||||
item[itemTextField] = getValue(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} `)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import * as React from 'react'
|
|||||||
import { LatLng } from 'leaflet'
|
import { LatLng } from 'leaflet'
|
||||||
import { Popup as LeafletPopup, useMap } from 'react-leaflet'
|
import { Popup as LeafletPopup, useMap } from 'react-leaflet'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useAddItem, useUpdateItem } from '../hooks/useItems'
|
import { useAddItem, useItems, useRemoveItem, useUpdateItem } from '../hooks/useItems'
|
||||||
import { Geometry, LayerProps, Item, ItemsApi } from '../../../types'
|
import { Geometry, LayerProps, Item, ItemsApi } from '../../../types'
|
||||||
import { TextAreaInput } from '../../Input/TextAreaInput'
|
import { TextAreaInput } from '../../Input/TextAreaInput'
|
||||||
import { TextInput } from '../../Input/TextInput'
|
import { TextInput } from '../../Input/TextInput'
|
||||||
@ -25,12 +25,17 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
|
|
||||||
const [spinner, setSpinner] = useState(false);
|
const [spinner, setSpinner] = useState(false);
|
||||||
|
|
||||||
|
const [popupTitle, setPopupTitle] = useState<string>("");
|
||||||
|
|
||||||
const formRef = useRef<HTMLFormElement>(null);
|
const formRef = useRef<HTMLFormElement>(null);
|
||||||
|
|
||||||
const map = useMap();
|
const map = useMap();
|
||||||
|
|
||||||
const addItem = useAddItem();
|
const addItem = useAddItem();
|
||||||
const updateItem = useUpdateItem();
|
const updateItem = useUpdateItem();
|
||||||
|
const items = useItems();
|
||||||
|
const removeItem = useRemoveItem();
|
||||||
|
|
||||||
|
|
||||||
const tags = useTags();
|
const tags = useTags();
|
||||||
const addTag = useAddTag();
|
const addTag = useAddTag();
|
||||||
@ -51,7 +56,7 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
setSpinner(true);
|
setSpinner(true);
|
||||||
|
|
||||||
formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag=> {
|
formItem.text && formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag=> {
|
||||||
if (!tags.find((t) => t.id.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
|
if (!tags.find((t) => t.id.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
|
||||||
addTag({id: tag.slice(1).toLocaleLowerCase(), color: randomColor()})
|
addTag({id: tag.slice(1).toLocaleLowerCase(), color: randomColor()})
|
||||||
}
|
}
|
||||||
@ -85,6 +90,16 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
toast.error(error.toString());
|
toast.error(error.toString());
|
||||||
}
|
}
|
||||||
if(success) {
|
if(success) {
|
||||||
|
console.log(props.layer);
|
||||||
|
|
||||||
|
if(props.layer.onlyOnePerOwner){
|
||||||
|
console.log(items);
|
||||||
|
|
||||||
|
const item = items.find(item => item.layer == props.layer && item.user_created?.id == user?.id);
|
||||||
|
console.log(item);
|
||||||
|
|
||||||
|
item && removeItem(item);
|
||||||
|
}
|
||||||
addItem({...formItem, id: uuid, layer: props.layer, user_created: user});
|
addItem({...formItem, id: uuid, layer: props.layer, user_created: user});
|
||||||
toast.success("New item created");
|
toast.success("New item created");
|
||||||
resetFilterTags();
|
resetFilterTags();
|
||||||
@ -119,14 +134,14 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
|||||||
<form ref={formRef} onReset={resetPopup} autoComplete='off' onSubmit={e => handleSubmit(e)}>
|
<form ref={formRef} onReset={resetPopup} autoComplete='off' onSubmit={e => handleSubmit(e)}>
|
||||||
{props.item ? <div className='tw-h-3'></div>
|
{props.item ? <div className='tw-h-3'></div>
|
||||||
:
|
:
|
||||||
<div className='tw-flex tw-justify-center'><b className="tw-text-xl tw-font-bold">New {props.layer.name}</b></div>
|
<div className='tw-flex tw-justify-center'><b className="tw-text-xl tw-font-bold">{ popupTitle? popupTitle : `New ${props.layer.name}`}</b></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{props.children ?
|
{props.children ?
|
||||||
|
|
||||||
React.Children.toArray(props.children).map((child) =>
|
React.Children.toArray(props.children).map((child) =>
|
||||||
React.isValidElement<{ item: Item, test: string }>(child) ?
|
React.isValidElement<{ item: Item, test: string, setPopupTitle: React.Dispatch<React.SetStateAction<string>> }>(child) ?
|
||||||
React.cloneElement(child, { item: props.item, key: props.position.toString() }) : ""
|
React.cloneElement(child, { item: props.item, key: props.position.toString(), setPopupTitle: setPopupTitle }) : ""
|
||||||
)
|
)
|
||||||
|
|
||||||
:
|
:
|
||||||
|
|||||||
@ -8,17 +8,19 @@ import Markdown from 'react-markdown'
|
|||||||
import rehypeVideo from 'rehype-video';
|
import rehypeVideo from 'rehype-video';
|
||||||
import { getValue } from '../../../../Utils/GetValue';
|
import { getValue } from '../../../../Utils/GetValue';
|
||||||
|
|
||||||
export const TextView = ({ item }: { item?: Item }) => {
|
export const TextView = ({ item, truncate = false}: { item?: Item, truncate?: boolean }) => {
|
||||||
const tags = useTags();
|
const tags = useTags();
|
||||||
const addFilterTag = useAddFilterTag();
|
const addFilterTag = useAddFilterTag();
|
||||||
|
|
||||||
const text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : undefined;
|
let text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : "";
|
||||||
|
|
||||||
|
if(item && text && truncate) text = truncateString(text, 100, true);
|
||||||
|
|
||||||
let replacedText;
|
let replacedText;
|
||||||
|
|
||||||
if (item && text) replacedText = fixUrls(text);
|
item && text ? replacedText = fixUrls(text) : "";
|
||||||
|
|
||||||
replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s\)]+(?!\))/g, (url) => {
|
replacedText ? replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s\)]+(?!\))/g, (url) => {
|
||||||
let shortUrl = url;
|
let shortUrl = url;
|
||||||
if (url.match('^https:\/\/')) {
|
if (url.match('^https:\/\/')) {
|
||||||
shortUrl = url.split('https://')[1];
|
shortUrl = url.split('https://')[1];
|
||||||
@ -27,15 +29,15 @@ export const TextView = ({ item }: { item?: Item }) => {
|
|||||||
shortUrl = url.split('http://')[1];
|
shortUrl = url.split('http://')[1];
|
||||||
}
|
}
|
||||||
return `[${shortUrl}](${url})`
|
return `[${shortUrl}](${url})`
|
||||||
})
|
}) : "" ;
|
||||||
|
|
||||||
replacedText = replacedText.replace(mailRegex, (url) => {
|
replacedText ? replacedText = replacedText.replace(mailRegex, (url) => {
|
||||||
return `[${url}](mailto:${url})`
|
return `[${url}](mailto:${url})`
|
||||||
})
|
}) : "";
|
||||||
|
|
||||||
replacedText = replacedText.replace(hashTagRegex, (match) => {
|
replacedText ? replacedText = replacedText.replace(hashTagRegex, (match) => {
|
||||||
return `[${match}](${match})`
|
return `[${match}](${match})`
|
||||||
})
|
}) : "";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -146,4 +148,12 @@ export const TextView = ({ item }: { item?: Item }) => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function truncateString( str, n, useWordBoundary ){
|
||||||
|
if (str.length <= n) { return str; }
|
||||||
|
const subString = str.slice(0, n-1); // the original check
|
||||||
|
return (useWordBoundary
|
||||||
|
? subString.slice(0, subString.lastIndexOf(" "))
|
||||||
|
: subString) + "…";
|
||||||
|
};
|
||||||
@ -29,6 +29,7 @@ export interface LayerProps {
|
|||||||
itemTagField?: string,
|
itemTagField?: string,
|
||||||
itemLatitudeField?: any,
|
itemLatitudeField?: any,
|
||||||
itemLongitudeField?: any,
|
itemLongitudeField?: any,
|
||||||
|
onlyOnePerOwner?: boolean,
|
||||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
|
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
|
||||||
itemFormPopup?: ItemFormPopupProps | null,
|
itemFormPopup?: ItemFormPopupProps | null,
|
||||||
clusterRef?: React.MutableRefObject<any>
|
clusterRef?: React.MutableRefObject<any>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user