// import dependencies import dotProp from 'dot-prop'; import { Card, CardContent } from '@mui/material'; import React, { useState, useEffect } from 'react'; import { Hbs, Box, Stack, Tooltip, Menu, Icon, Badge, IconButton, Avatar, Chip, View, useTheme } from '../'; // create menu component const DashupUIItem = (props = {}) => { // theme const theme = useTheme(); // use state const [count, setCount] = useState(0); const [updated, setUpdated] = useState(new Date()); const [tagOpen, setTagOpen] = useState(false); const [userOpen, setUserOpen] = useState(false); // add listeners useEffect(() => { // check page if (!props.page) return; // on update const onUpdate = () => { // updated setUpdated(new Date()); }; // on update props.dashup.action({ type : 'page', struct : 'channel', }, 'count', props.item.get('_id')).then(setCount); props.dashup.socket.on(`count.${props.item.get('_id')}`, setCount); // on update props.item.on('update', onUpdate); // return unlisten return () => { // off props.item.removeListener('update', onUpdate); props.dashup.socket.off(`count.${props.item.get('_id')}`, setCount); }; }, [props.item && props.item.get('_id'), props.page && props.page.get('_id')]); // get color const getColor = () => { // color tag const colorTag = hasTags() && getTags(getTagFields().find((t) => getTags(t).length))[0]; // get color return colorTag?.color ? { color : colorTag.color?.hex && theme.palette.getContrastText(colorTag.color?.hex), backgroundColor : colorTag.color?.hex, } : null; }; // get tag types const getTagFields = () => { // check get field if (!props.getField) return []; // set types let types = typeof props.tag !== 'undefined' ? props.tag : (props.page.get('data.tag') || []); if (!Array.isArray(types)) types = [types]; // return fields return types.map((f) => props.getField(f)).filter((f) => f); }; // get user types const getUserFields = () => { // check get field if (!props.getField) return []; // set types let types = typeof props.user !== 'undefined' ? props.user : (props.page.get('data.user') || []); if (!Array.isArray(types)) types = [types]; // return fields return types.map((f) => props.getField(f)).filter((f) => f); } // get tags const getTags = (tagField) => { // tag field if (!tagField) return []; // get options const options = tagField.options || []; // check options if (!options.length) return []; // get value let val = props.item.get(tagField.name || tagField.uuid) || []; // set value if (!Array.isArray(val)) val = [val].filter((v) => v); // tags return options.filter((t) => { // return has tag return val.includes(t.value); }); }; // get users const getUsers = (userField) => { // check options if (!userField) return []; // get value let val = props.item.get(userField.name || userField.uuid) || []; // set value if (!Array.isArray(val)) val = [val].filter((v) => v); // tags return val; }; // has tags const hasTags = () => { // check page if (!props.page) return; // tag uuid return !!(props.tag || props.page.get('data.tag') || []).length; }; // on tag const onUser = (field, value) => { // check multiple if (Array.isArray(value) && !field.multiple) value = value[0] || null; // get tag value props.item.set(field.name || field.uuid, value); props.item.save(); }; // on tag const onTag = (field, value) => { // check multiple if (Array.isArray(value) && !field.multiple) value = value[0] || null; // set and save props.item.set(field.name || field.uuid, value); props.item.save(); }; // return jsx return (!props.item || !props.item.toJSON || props.item.get('archived')) ? null : ( <> { !!hasTags() && ( { getTagFields().map((type, i) => { // return jsx return ( { getTags(type).map((tag, a) => { // get color const color = tag.color?.hex; // return jsx return ( setTagOpen({ ...type, el : e.target }) } onDelete={ () => onTag(type, getTags(type).filter((t) => t.value !== tag.value)) } /> ); }) } setTagOpen({ ...type, el : e.target }) } size="small"> ); }) } ) } props.onClick(props.item) } sx={ { py : props.size === 'sm' ? 1 : undefined, px : props.size === 'sm' ? 1 : undefined, color : props.color && theme.palette.getContrastText(dotProp.get(theme.palette, props.color)), cursor : 'pointer', ...(props.BodyProps?.sx), } }> { !!props.repeat && ( ) } { getUserFields().map((type, i) => { // return jsx return ( { getUsers(type).map((user, a) => { // get image let image = Array.isArray(user.image || user.avatar) ? (user.image || user.avatar)[0] : (user.image || user.avatar); image = typeof image === 'string' ? image : dotProp.get(image, 'thumbs.1x-sq.url'); // return jsx return ( : null } onClick={ (e) => setUserOpen({ ...type, el : e.target }) } onDelete={ () => onUser(type, getUsers(type).filter((u) => u.id !== user.id)) } /> ); }) } setUserOpen({ ...type, el : e.target }) } size="small"> ); }) } props.onClick(props.item) }> { !!userOpen?.type && ( setUserOpen(null) } anchorEl={ userOpen.el } MenuListProps={ { sx : { width : 240, padding : theme.spacing(1), }, } } > ) } { !!tagOpen?.type && ( setTagOpen(null) } anchorEl={ tagOpen.el } MenuListProps={ { sx : { width : 240, padding : theme.spacing(1), }, } } > ) } ); }; // export default export default DashupUIItem;