import type { Entity } from "bknd";
import { repoQuery } from "data/server/query";
import { Fragment } from "react";
import { TbDots } from "react-icons/tb";
import { useApiQuery } from "ui/client";
import { useBknd } from "ui/client/bknd";
import { useBkndData } from "ui/client/schema/data/use-bknd-data";
import { Button } from "ui/components/buttons/Button";
import { IconButton } from "ui/components/buttons/IconButton";
import { Message } from "ui/components/display/Message";
import { Dropdown } from "ui/components/overlay/Dropdown";
import { useBrowserTitle } from "ui/hooks/use-browser-title";
import { useSearch } from "ui/hooks/use-search";
import * as AppShell from "ui/layouts/AppShell/AppShell";
import { routes, useNavigate } from "ui/lib/routes";
import { useCreateUserModal } from "ui/modules/auth/hooks/use-create-user-modal";
import { EntityTable2 } from "ui/modules/data/components/EntityTable2";
import { s } from "bknd/utils";
import { pick } from "core/utils/objects";
const searchSchema = s.partialObject({
...pick(repoQuery.properties, ["select", "where", "sort"]),
page: s.number({ default: 1 }).optional(),
perPage: s.number({ default: 10 }).optional(),
});
const PER_PAGE_OPTIONS = [5, 10, 25, 50, 100];
export function DataEntityList({ params }) {
return ;
}
function DataEntityListImpl({ params }) {
const { $data } = useBkndData();
const entity = $data.entity(params.entity as string);
if (!entity) {
return ;
}
useBrowserTitle(["Data", entity?.label ?? params.entity]);
const [navigate] = useNavigate();
const search = useSearch(searchSchema, {
defaultValue: {
select: entity.getSelect(undefined, "table"),
sort: entity.getDefaultSort(),
},
beforeEncode: (v) => {
if ("sort" in v && v.sort) {
return {
...v,
sort: `${v.sort.dir === "asc" ? "" : "-"}${v.sort.by}`,
};
}
return v;
},
});
const $q = useApiQuery(
(api) =>
api.data.readMany(entity?.name as any, {
select: search.value.select,
limit: search.value.perPage,
offset: (search.value.page - 1) * search.value.perPage,
sort: `${search.value.sort.dir === "asc" ? "" : "-"}${search.value.sort.by}`,
}),
{
enabled: !!entity,
revalidateOnFocus: true,
keepPreviousData: true,
},
);
const data = $q.data?.data;
const meta = $q.data?.body.meta;
function handleClickRow(row: Record) {
if (entity) navigate(routes.data.entity.edit(entity.name, row.id));
}
function handleClickPage(page: number) {
search.set({ page });
}
function handleSortClick(name: string) {
const sort = search.value.sort!;
const newSort = { by: name, dir: sort.by === name && sort.dir === "asc" ? "desc" : "asc" };
search.set({ sort: newSort as any });
}
function handleClickPerPage(perPage: number) {
search.set({ perPage, page: 1 });
}
const isUpdating = $q.isLoading || $q.isValidating;
return (
navigate(routes.data.schema.entity(entity.name)),
},
{
label: "Data Schema",
onClick: () => navigate(routes.data.schema.root()),
},
{
label: "Advanced Settings",
onClick: () =>
navigate(routes.settings.path(["data", "entities", entity.name]), {
absolute: true,
}),
},
]}
position="bottom-end"
>
>
}
>
{entity.label}
);
}
function EntityCreateButton({ entity }: { entity: Entity }) {
const b = useBknd();
const createUserModal = useCreateUserModal();
const [navigate] = useNavigate();
if (!entity) return null;
if (entity.type === "system") {
const system = {
users: b.app.config.auth.entity_name,
media: b.app.config.media.entity_name,
};
if (system.users === entity.name) {
return (
);
}
return null;
}
return (
);
}