Skip to content

Commit

Permalink
Popper preview for selected items
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Tilsch committed Feb 12, 2024
1 parent ac7bd51 commit 62f242c
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useGlobalCRUDOptions } from "../state/useGlobalCRUDOptions";
import { JsonView } from "react-json-view-lite";
import { Grid, List, TextField } from "@mui/material";
import ClassicResultListItem from "../form/result/ClassicResultListItem";
import {sladb} from "../form/formConfigs";

export default {
title: "forms/mapping/LobidMapping",
Expand Down Expand Up @@ -76,7 +77,7 @@ const LobidMappingTester = ({
</Grid>
<LobidSearchTable
searchString=""
typeName={typeName}
typeIRI={sladb[typeName].value}
selectedId={gndID}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/exhibition-live/components/form/SimilarityFinder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ const SimilarityFinder: FunctionComponent<Props> = ({
<LobidSearchTable
onAcceptItem={handleAccept}
searchString={searchString}
typeName={typeName}
typeIRI={classIRI}
onSelect={handleSelectGND}
/>
<Divider />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { sladb } from "../formConfigs";
import ClassicEntityCard from "../lobid/ClassicEntityCard";
import LobidAllPropTable from "../lobid/LobidAllPropTable";
import ClassicResultListItem from "../result/ClassicResultListItem";
import { EntityDetailElement } from "../show";

type Props = {
searchString: string;
Expand All @@ -34,6 +35,7 @@ const DiscoverSearchTable: FunctionComponent<Props> = ({
const [selectedId, setSelectedId] = useState<string | undefined>();
const [selectedEntry, setSelectedEntry] = useState<any | undefined>();
const { crudOptions } = useGlobalCRUDOptions();
const typeIRI = sladb[typeName].value;

const fetchData = useCallback(async () => {
if (!searchString || searchString.length < 1 || !crudOptions) return;
Expand Down Expand Up @@ -94,6 +96,18 @@ const DiscoverSearchTable: FunctionComponent<Props> = ({
avatar={avatar}
altAvatar={idx + 1}
selected={selectedIndex === idx}
popperChildren={
<EntityDetailElement
sx={{
maxWidth: "30em",
maxHeight: "80vh",
overflow: "auto",
}}
entityIRI={id}
typeIRI={typeIRI}
data={undefined}
/>
}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { ComponentMeta } from "@storybook/react";
import React from "react";

import LobidSearchTable from "./LobidSearchTable";
import {sladb} from "../formConfigs";

export default {
title: "form/lobid/LobidSearchTable",
component: LobidSearchTable,
} as ComponentMeta<typeof LobidSearchTable>;

export const LobidSearchTableDefault = () => (
<LobidSearchTable searchString={"Ada Love"} />
<LobidSearchTable typeIRI={sladb["Person"].value} searchString={"Ada Love"} />
);
20 changes: 15 additions & 5 deletions apps/exhibition-live/components/form/lobid/LobidSearchTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ import {
extractFieldIfString,
} from "../../utils/mapping/simpleFieldExtractor";
import { useQuery } from "@tanstack/react-query";
import { EntityDetailElement } from "../show";
import { sladb } from "../formConfigs";
import {typeIRItoTypeName} from "../../config";

type Props = {
searchString: string;
typeName?: string;
typeIRI: string;
selectedId?: string | null;
onSelect?: (id: string | undefined) => void;
onAcceptItem?: (id: string | undefined, data: any) => void;
Expand Down Expand Up @@ -99,7 +102,7 @@ export const gndEntryWithMainInfo = (allProps: any) => {

const LobidSearchTable: FunctionComponent<Props> = ({
searchString,
typeName = "Person",
typeIRI,
onSelect,
onAcceptItem,
selectedId: selectedIdProp,
Expand All @@ -115,11 +118,11 @@ const LobidSearchTable: FunctionComponent<Props> = ({
const fetchData = useCallback(async () => {
if (!searchString || searchString.length < 1) return;
setResultTable(
(await findEntityWithinLobid(searchString, typeName, 10))?.member?.map(
(await findEntityWithinLobid(searchString, typeIRItoTypeName(typeIRI), 10))?.member?.map(
(allProps: any) => gndEntryWithMainInfo(allProps),
),
);
}, [searchString, typeName]);
}, [searchString, typeIRI]);

const { data: rawEntry } = useQuery(
["lobid", selectedId],
Expand All @@ -144,7 +147,7 @@ const LobidSearchTable: FunctionComponent<Props> = ({

useEffect(() => {
fetchData();
}, [searchString, typeName, fetchData]);
}, [searchString, typeIRI, fetchData]);

return (
<>
Expand Down Expand Up @@ -185,6 +188,13 @@ const LobidSearchTable: FunctionComponent<Props> = ({
secondary={secondary}
avatar={avatar}
altAvatar={String(idx + 1)}
popperChildren={
<EntityDetailElement
entityIRI={id}
typeIRI={typeIRI}
data={undefined}
/>
}
/>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
} from "@mui/material";
import { useTheme } from "@mui/material/styles";
import * as React from "react";
import { FunctionComponent, useCallback } from "react";
import { FunctionComponent, useCallback, useEffect, useState } from "react";
import { ClassicResultPopperItem } from "./ClassicResultPopperItem";

type OwnProps = {
id: string;
Expand All @@ -20,6 +21,7 @@ type OwnProps = {
label: string;
secondary?: string;
altAvatar?: string;
popperChildren?: React.ReactNode;
};

type Props = OwnProps & ListItemButtonProps;
Expand All @@ -31,9 +33,22 @@ const ClassicResultListItem: FunctionComponent<Props> = ({
label,
secondary,
altAvatar,
selected,
popperChildren,
...rest
}) => {
const theme = useTheme();
const anchorRef = React.useRef(null);
const [afterTimeout, setAfterTimeout] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => {
setAfterTimeout(true);
}, 200);
return () => {
clearTimeout(timeout)
setAfterTimeout(false)
};
}, []);

const handleSelect = useCallback(() => {
onSelected(id);
Expand All @@ -48,6 +63,8 @@ const ClassicResultListItem: FunctionComponent<Props> = ({
"&:hover": { backgroundColor: "transparent" },
}}
onClick={handleSelect}
ref={anchorRef}
selected={selected}
{...rest}
>
<ListItemAvatar>
Expand Down Expand Up @@ -76,6 +93,12 @@ const ClassicResultListItem: FunctionComponent<Props> = ({
/>
</ListItemButton>
</ListItem>
<ClassicResultPopperItem
anchorEl={anchorRef.current}
open={selected && afterTimeout}
>
{popperChildren}
</ClassicResultPopperItem>
<Divider variant="inset" component="li" />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
Box,
Paper,
Popper as MuiPopper,
PopperProps,
styled,
} from "@mui/material";
import { FunctionComponent } from "react";
import * as React from "react";

const Arrow = styled("div")({
position: "absolute",
fontSize: 16,
width: "3em",
height: "3em",
right: "1em !important",
"&::before": {
content: '""',
margin: "auto",
display: "block",
width: 0,
height: 0,
borderStyle: "solid",
},
});

const Popper = styled(MuiPopper, {
shouldForwardProp: (prop) => prop !== "arrow",
})(({ theme }) => {
const arrow = true;
return {
zIndex: 1,
"& > div": {
position: "relative",
},
'&[data-popper-placement*="bottom"]': {
"& > div": {
marginTop: arrow ? 2 : 0,
},
"& .MuiPopper-arrow": {
top: 0,
left: 0,
marginTop: "-0.9em",
width: "3em",
height: "1em",
"&::before": {
borderWidth: "0 1em 1em 1em",
borderColor: `transparent transparent ${theme.palette.background.paper} transparent`,
},
},
},
'&[data-popper-placement*="top"]': {
"& > div": {
marginBottom: arrow ? 2 : 0,
},
"& .MuiPopper-arrow": {
bottom: 0,
left: 0,
marginBottom: "-0.9em",
width: "3em",
height: "1em",
"&::before": {
borderWidth: "1em 1em 0 1em",
borderColor: `${theme.palette.background.paper} transparent transparent transparent`,
},
},
},
'&[data-popper-placement*="right"]': {
"& > div": {
marginLeft: arrow ? 2 : 0,
},
"& .MuiPopper-arrow": {
left: 0,
marginLeft: "-0.9em",
height: "3em",
width: "1em",
"&::before": {
borderWidth: "1em 1em 1em 0",
borderColor: `transparent ${theme.palette.background.paper} transparent transparent`,
},
},
},
'&[data-popper-placement*="left"]': {
"& > div": {
marginRight: arrow ? 2 : 0,
},
"& .MuiPopper-arrow": {
right: 0,
marginRight: "-0.9em",
height: "3em",
width: "1em",
"&::before": {
borderWidth: "1em 0 1em 1em",
borderColor: `transparent transparent transparent ${theme.palette.background.paper}`,
},
},
},
};
});

export const ClassicResultPopperItem: FunctionComponent<
{ children: React.ReactNode } & PopperProps
> = ({ children, ...rest }) => {
const [arrowRef, setArrowRef] = React.useState<HTMLElement>(null);

return (
<Box sx={{ position: "relative" }}>
<Popper
{...rest}
placement="left"
disablePortal={false}
modifiers={[
{
name: "flip",
enabled: true,
options: {
altBoundary: true,
rootBoundary: "document",
padding: 8,
},
},
{
name: "arrow",
enabled: true,
options: {
element: arrowRef,
},
},
]}
>
<Box>
<Arrow ref={setArrowRef} className="MuiPopper-arrow" />
<Paper sx={{ p: 2, m: 2 }} elevation={2}>
{children}
</Paper>
</Box>
</Popper>
</Box>
);
};
16 changes: 5 additions & 11 deletions apps/exhibition-live/components/form/show/EntityDetailElement.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import {
AppBar,
Box,
Grid,
IconButton,
Toolbar,
Typography,
} from "@mui/material";
import { Close as CloseIcon } from "@mui/icons-material";
import { Box, BoxProps } from "@mui/material";
import useExtendedSchema from "../../state/useExtendedSchema";
import { useGlobalCRUDOptions } from "../../state/useGlobalCRUDOptions";
import { useCRUDWithQueryClient } from "../../state/useCRUDWithQueryClient";
Expand All @@ -32,7 +24,9 @@ export const EntityDetailElement = ({
typeIRI,
entityIRI,
data: liveData,
}: EntityDetailElementProps) => {
...rest
}: EntityDetailElementProps & Partial<BoxProps>) => {
const boxProps = rest || {};
const typeIRIs = useTypeIRIFromEntity(entityIRI);
const classIRI: string | undefined = typeIRI || typeIRIs?.[0];
const typeName = useMemo(() => typeIRItoTypeName(classIRI), [classIRI]);
Expand Down Expand Up @@ -64,7 +58,7 @@ export const EntityDetailElement = ({
}, [typeName, data]);

return (
<Box sx={{ p: 2 }}>
<Box sx={{ p: 2, ...(rest.sx || {}) }} {...rest}>
<EntityDetailCard
typeIRI={classIRI}
entityIRI={entityIRI}
Expand Down

0 comments on commit 62f242c

Please sign in to comment.