Skip to content

Commit

Permalink
fix(web): search areas template height
Browse files Browse the repository at this point in the history
  • Loading branch information
ascariandrea committed Dec 30, 2023
1 parent aba9f9b commit fa7e5b5
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const AutocompleteActorInput: React.FC<AutocompleteActorInputProps> = ({
<AutocompleteInput<Actor.Actor>
disablePortal={true}
placeholder="Actors..."
getValue={(a) => (typeof a === "string" ? a : a.fullName)}
getOptionLabel={(a) => (typeof a === "string" ? a : a.fullName)}
searchToFilter={(fullName) => ({ fullName })}
selectedItems={selectedItems}
query={(p) =>
Expand Down
72 changes: 72 additions & 0 deletions packages/@liexp/ui/src/components/Input/AutocompleteAreaInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { type Area } from "@liexp/shared/lib/io/http";
import * as React from "react";
import { useEndpointQueries } from "../../hooks/useEndpointQueriesProvider";
import { AreaList, AreaListItem } from "../lists/AreaList";
import { Grid, Typography } from "../mui";
import { AutocompleteInput } from "./AutocompleteInput";

export interface AutocompleteAreaInputProps {
className?: string;
selectedItems: Area.Area[];
onChange: (items: Area.Area[]) => void;
discrete?: boolean;
}

export const AutocompleteAreaInput: React.FC<AutocompleteAreaInputProps> = ({
selectedItems,
onChange,
discrete = true,
...props
}) => {
const Queries = useEndpointQueries();
return (
<AutocompleteInput<Area.Area>
placeholder="Search area..."
getOptionLabel={(a) => (typeof a === "string" ? a : a.label)}
searchToFilter={(description) => ({ description })}
selectedItems={selectedItems}
query={(p) => Queries.Area.list.useQuery(p, undefined, discrete, 'search')}
renderTags={(items) => (
<AreaList
areas={items.map((i) => ({
...i,
selected: true,
}))}
style={{ flexWrap: "wrap", flexDirection: "column" }}
onAreaClick={(a) => {
onChange(items.filter((i) => i.id !== a.id));
}}
/>
)}
renderOption={(props, item, state) => {
return (
<Grid
container
spacing={2}
key={item.id}
onClick={() => {
onChange(
selectedItems.filter((i) => i.id !== item.id).concat(item),
);
}}
>
<Grid item md={3}>
<AreaListItem
item={{
...item,
selected: false,
}}
style={{ height: 100 }}
/>
</Grid>
<Grid item md={9}>
<Typography variant="subtitle1">{item.label}</Typography>
</Grid>
</Grid>
);
}}
onItemsChange={onChange}
{...props}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const AutocompleteEventInput: React.FC<AutocompleteEventInputProps> = ({
return (
<AutocompleteInput<Events.Event>
placeholder="Event description..."
getValue={(a) =>
getOptionLabel={(a) =>
typeof a === "string"
? a
: getTitle(a, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const AutocompleteGroupInput: React.FC<AutocompleteGroupInputProps> = ({
return (
<AutocompleteInput<Group.Group>
placeholder="Groups..."
getValue={(a) => (typeof a === "string" ? a : a.name)}
getOptionLabel={(a) => (typeof a === "string" ? a : a.name)}
searchToFilter={(name) => ({ name })}
selectedItems={selectedItems}
query={(p) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const AutocompleteGroupMemberInput: React.FC<
placeholder="Group Member..."
searchToFilter={(tag) => ({ tag })}
selectedItems={selectedItems}
getValue={(k) =>
getOptionLabel={(k) =>
typeof k === "string" ? k : `${k.group.name} - ${k.actor.fullName}`
}
query={(p) => Queries.GroupMember.list.useQuery(p, undefined, true)}
Expand Down
91 changes: 51 additions & 40 deletions packages/@liexp/ui/src/components/Input/AutocompleteInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,94 +19,105 @@ export interface AutocompleteInputProps<T extends SearchableItem>
params: GetListParams,
) => UseQueryResult<{ data: T[]; total: number }, APIError>;
searchToFilter: (t: string) => Record<string, string>;
getValue: (v: T | string) => string;
getOptionLabel: (v: T | string) => string;
selectedItems: T[];
onItemsChange: (items: T[]) => void;
}

export const AutocompleteInput = <T extends { id: string }>({
query,
selectedItems,
getValue,
getOptionLabel,
placeholder,
renderTags,
renderOption,
searchToFilter,
onItemsChange,
...props
}: AutocompleteInputProps<T>): React.ReactElement => {
const selectedIds = selectedItems.map((s) => s.id);
const [value, setValue] = React.useState<string>("");
// const setValueThrottled = throttle(300, setValue, true);
const [inputValue, setInputValue] = React.useState<string>("");
const selectedIds = React.useMemo(
() => selectedItems.map((s) => s.id),
[selectedItems],
);

// params
const itemQueryParams = React.useMemo(() => {
const filter =
value !== undefined && value !== ""
? searchToFilter(value)
inputValue !== undefined && inputValue !== ""
? searchToFilter(inputValue)
: selectedIds.length > 0
? { ids: selectedIds }
: {};
: null;
return {
sort: { field: "createdAt", order: "DESC" as const },
pagination: { page: 1, perPage: 20 },
filter,
};
}, [value]);
}, [inputValue]);

// queries
const items = query(itemQueryParams);
const data = items.data?.data ?? [];

const handleValueChange = React.useCallback(
(v: string) => {
setValue(v);
},
[value],
);
const { options, value } = React.useMemo(() => {
const options = data.filter((i) => !selectedIds.includes(i.id));

const items = query(itemQueryParams);
const value = data.filter((i) => selectedIds.includes(i.id));
return { options, value };
}, [data, selectedIds]);

if (items.isError) {
return (
<ErrorBox
error={items.error}
resetErrorBoundary={() => {
setValue("");
setInputValue("");
}}
/>
);
}

console.log({ value, inputValue })

Check failure on line 80 in packages/@liexp/ui/src/components/Input/AutocompleteInput.tsx

View workflow job for this annotation

GitHub Actions / pull_request

Unexpected console statement

return (
<Autocomplete<T, boolean, boolean, boolean>
{...props}
size="small"
inputValue={value}
value={(items.data?.data ?? []).filter((i) => selectedIds.includes(i.id))}
options={(items.data?.data ?? []).filter(
(i) => !selectedIds.includes(i.id),
)}
onChange={(e, v) => {
disablePortal
multiple
openOnFocus
inputValue={inputValue}
onInputChange={(e, v, r) => {
console.log('on input change', v, r);

Check failure on line 90 in packages/@liexp/ui/src/components/Input/AutocompleteInput.tsx

View workflow job for this annotation

GitHub Actions / pull_request

Unexpected console statement
if (r === "input") {
setInputValue(v);
}
}}
value={value}
options={options}
onChange={(e, v, r, d) => {
console.log('on change', v, r, d);

Check failure on line 98 in packages/@liexp/ui/src/components/Input/AutocompleteInput.tsx

View workflow job for this annotation

GitHub Actions / pull_request

Unexpected console statement
if (Array.isArray(v)) {
onItemsChange(v as T[]);
handleValueChange("");
setInputValue("");
}
}}
getOptionLabel={getValue}
renderInput={(params) => (
<TextField
{...params}
placeholder={placeholder}
variant="standard"
onChange={(e) => {
const v = e.target.value;
handleValueChange(v);
}}
/>
)}
disablePortal={true}
multiple={true}
getOptionLabel={getOptionLabel}
renderInput={(params) => {
console.log('render input', params);

Check failure on line 106 in packages/@liexp/ui/src/components/Input/AutocompleteInput.tsx

View workflow job for this annotation

GitHub Actions / pull_request

Unexpected console statement
return (
<TextField
{...params}
placeholder={placeholder}
InputProps={{
...params.InputProps,
type: "search",
}}
/>
);
}}
renderTags={renderTags}
renderOption={renderOption}
{...props}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const AutocompleteKeywordInput: React.FC<
placeholder="Keyword..."
searchToFilter={(search) => ({ search })}
selectedItems={selectedItems}
getValue={(k) => (typeof k === "string" ? k : k.tag)}
getOptionLabel={(k) => (typeof k === "string" ? k : k.tag)}
query={(p) =>
options
? useQuery(["keyword-options"], () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const AutocompleteLinkInput: React.FC<AutocompleteLinkInputProps> = ({
return (
<AutocompleteInput<Link.Link>
placeholder="Search in links..."
getValue={(a) =>
getOptionLabel={(a) =>
typeof a === "string" ? a : a.description ?? a.title ?? "no description"
}
searchToFilter={(description) => ({ description })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const AutocompleteMediaInput: React.FC<AutocompleteMediaInputProps> = ({
return (
<AutocompleteInput<Media.Media>
placeholder="Media description..."
getValue={(a) =>
getOptionLabel={(a) =>
typeof a === "string"
? a
: a?.label ?? a?.description ?? "No description"
Expand Down
15 changes: 8 additions & 7 deletions packages/@liexp/ui/src/components/lists/AreaList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from "react";
import { useEndpointQueries } from "../../hooks/useEndpointQueriesProvider";
import { styled } from "../../theme";
import { List, type ListItemProps } from "../Common/List";
import { defaultImage } from "../SEO";
import {
Card,
CardActionArea,
Expand Down Expand Up @@ -53,6 +54,8 @@ export const AreaListItem: React.FC<
true,
);

const mediaSrc = media.data?.data?.[0]?.location ?? defaultImage;

return (
<StyledBox
key={item.id}
Expand All @@ -64,13 +67,11 @@ export const AreaListItem: React.FC<
>
<Card className={classes.root}>
<CardActionArea>
{(media.data?.data?.length ?? 0) > 0 ? (
<CardMedia
className={classes.media}
image={(media.data as any).data[0].location}
title={item.label}
/>
) : null}
<CardMedia
className={classes.media}
image={mediaSrc}
title={item.label}
/>
<CardContent>
<Typography gutterBottom variant="h6" component="h3">
{item.label}
Expand Down
79 changes: 79 additions & 0 deletions packages/@liexp/ui/src/containers/areas/ExploreAreasBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { type Area } from "@liexp/shared/lib/io/http";
import * as React from "react";
import { AutoSizer } from "react-virtualized";
import AreasMap from "../../components/AreasMap";
import QueriesRenderer from "../../components/QueriesRenderer";
import { AreaList } from "../../components/lists/AreaList";
import { Box, Grid } from "../../components/mui";

interface ExploreAreasBoxProps {
onAreaClick: (a: Area.Area) => void;
}

export const ExploreAreasBox: React.FC<ExploreAreasBoxProps> = ({
onAreaClick,
}) => {
return (
<QueriesRenderer
queries={(Q) => ({
areas: Q.Area.list.useQuery(
{
filter: null,
},
undefined,
false,
),
})}
render={({ areas: { data: areas } }) => {
return (
<AutoSizer
defaultHeight={600}
style={{ width: "100%", height: "100%" }}
>
{({ width, height }) => {
const innerHeight = height - height * 0.2;
return (
<Grid
container
spacing={2}
style={{ height: innerHeight, width: "100%" }}
>
<Grid item md={8}>
<Box style={{ width: "100%", maxHeight: "100%" }}>
<AreasMap
areas={areas}
height={height * (2 / 3)}
onMapClick={(features) => {
if (features.length > 0) {
const area: any = features[0].getProperties();
onAreaClick(area);
}
}}
/>
</Box>
</Grid>
<Grid
item
md={4}
style={{ height: innerHeight, overflow: "auto" }}
>
<AreaList
areas={areas.map((a) => ({ ...a, selected: false }))}
onAreaClick={onAreaClick}
style={{
display: "flex",
flexDirection: "column",
width: "100%",
height: "100%",
}}
/>
</Grid>
</Grid>
);
}}
</AutoSizer>
);
}}
/>
);
};
Loading

0 comments on commit fa7e5b5

Please sign in to comment.