el.xwx.moe/components/InputSelect/CollectionSelection.tsx

131 lines
3.3 KiB
TypeScript
Raw Normal View History

2023-03-22 18:11:54 -05:00
import useCollectionStore from "@/store/collections";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { styles } from "./styles";
import { Options } from "./types";
import CreatableSelect from "react-select/creatable";
2024-07-25 18:58:52 -05:00
import Select, { ActionMeta } from "react-select";
2023-03-28 02:31:50 -05:00
type Props = {
2024-07-25 18:58:52 -05:00
onChange: (newValue: unknown, actionMeta: ActionMeta<unknown>) => void;
showDefaultValue?: boolean;
2024-02-10 16:23:59 -06:00
defaultValue?:
2024-07-25 18:58:52 -05:00
| {
label: string;
value?: number;
}
| undefined;
2024-02-14 07:10:45 -06:00
creatable?: boolean;
2023-03-28 02:31:50 -05:00
};
2024-02-11 01:29:11 -06:00
export default function CollectionSelection({
onChange,
defaultValue,
showDefaultValue = true,
2024-02-14 07:10:45 -06:00
creatable = true,
2024-02-11 01:29:11 -06:00
}: Props) {
2023-03-22 18:11:54 -05:00
const { collections } = useCollectionStore();
const router = useRouter();
const [options, setOptions] = useState<Options[]>([]);
const collectionId = Number(router.query.id);
const activeCollection = collections.find((e) => {
return e.id === collectionId;
});
2023-03-28 02:31:50 -05:00
if (activeCollection && !defaultValue) {
defaultValue = {
2023-02-24 22:22:33 -06:00
value: activeCollection?.id,
label: activeCollection?.name,
};
}
useEffect(() => {
const formatedCollections = collections.map((e) => {
2024-02-19 13:37:07 -06:00
return {
value: e.id,
label: e.name,
ownerId: e.ownerId,
count: e._count,
parentId: e.parentId,
};
});
setOptions(formatedCollections);
}, [collections]);
2024-02-18 03:32:31 -06:00
const getParentNames = (parentId: number): string[] => {
const parentNames = [];
const parent = collections.find((e) => e.id === parentId);
if (parent) {
parentNames.push(parent.name);
if (parent.parentId) {
parentNames.push(...getParentNames(parent.parentId));
}
}
// Have the top level parent at beginning
return parentNames.reverse();
2024-02-19 13:37:07 -06:00
};
2024-02-18 03:32:31 -06:00
const customOption = ({ data, innerProps }: any) => {
return (
<div
{...innerProps}
2024-02-19 13:37:07 -06:00
className="px-2 py-2 last:border-0 border-b border-neutral-content hover:bg-neutral-content cursor-pointer"
2024-02-18 03:32:31 -06:00
>
<div className="flex w-full justify-between items-center">
2024-02-19 13:37:07 -06:00
<span>{data.label}</span>
<span className="text-sm text-neutral">{data.count?.links}</span>
2024-02-18 03:32:31 -06:00
</div>
<div className="text-xs text-gray-600 dark:text-gray-300">
{getParentNames(data?.parentId).length > 0 ? (
<>
2024-02-19 13:37:07 -06:00
{getParentNames(data.parentId).join(" > ")} {">"} {data.label}
2024-02-18 03:32:31 -06:00
</>
) : (
data.label
)}
</div>
</div>
);
};
2024-02-14 07:10:45 -06:00
if (creatable) {
return (
<CreatableSelect
isClearable={false}
className="react-select-container"
classNamePrefix="react-select"
onChange={onChange}
options={options}
styles={styles}
defaultValue={showDefaultValue ? defaultValue : null}
2024-02-18 03:32:31 -06:00
components={{
Option: customOption,
}}
2024-07-25 18:58:52 -05:00
// menuPosition="fixed"
2024-02-14 07:10:45 -06:00
/>
);
} else {
return (
<Select
isClearable={false}
className="react-select-container"
classNamePrefix="react-select"
onChange={onChange}
options={options}
styles={styles}
defaultValue={showDefaultValue ? defaultValue : null}
2024-02-19 13:37:07 -06:00
components={{
Option: customOption,
}}
2024-07-25 18:58:52 -05:00
// menuPosition="fixed"
2024-02-14 07:10:45 -06:00
/>
);
}
}