@npio/internals
Version:
A free visual website editor, powered with your own SolidJS components.
175 lines (156 loc) • 3.41 kB
text/typescript
import { createIdMap } from "../../normalization";
import { deleteElements } from "../element";
import { useDatabase } from "../prisma";
import { getRevision } from "../revision";
export const getLayout = async (id: string) => {
const db = useDatabase();
const layout = await db.nitroPage.findUnique({
select: {
id: true,
publishedRevision: {
select: {
id: true,
},
},
layoutSlots: {
omit: {
createdAt: true,
updatedAt: true,
},
},
},
where: {
type: "layout",
id,
publishedRevision: {
isNot: null,
},
},
});
if (!layout) return;
const revision = await getRevision(layout.publishedRevision!.id);
if (!revision) return;
return {
...layout,
layoutSlots: createIdMap(layout.layoutSlots, (ls) => ({
...ls,
consumerSlots: [],
elementSlots: [],
})),
revision,
};
};
export const getUsedLayouts = async (pageId: string) => {
const db = useDatabase();
const result = await db.nitroElement.groupBy({
by: ["layoutId"],
where: {
page: {
pageId,
},
layout: {
isNot: null,
},
},
});
let layoutIds: string[] = [];
for (const item of result) {
layoutIds.push(item.layoutId!);
const itemResult = await getUsedLayouts(item.layoutId!);
layoutIds = [...layoutIds, ...itemResult];
}
return layoutIds;
};
export type Layout = NonNullable<Awaited<ReturnType<typeof getLayout>>>;
export const getValidLayouts = async (pageId: string) => {
const db = useDatabase();
const page = await db.nitroPage.findUnique({
where: {
id: pageId,
},
});
if (!page) return;
const layouts = await db.nitroPage.findMany({
select: {
id: true,
publishedRevision: {
select: {
id: true,
title: true,
},
},
layoutSlots: {
select: {
id: true,
},
},
},
where: {
AND: [
{
NOT: {
id: pageId,
},
},
{
type: "layout",
projectId: page.projectId,
publishedRevision: {
isNot: null,
},
},
],
},
});
let validLayouts = layouts;
if (page.type === "layout") {
validLayouts = [];
for (const layout of layouts) {
const result = await getUsedLayouts(layout.id);
if (result.includes(pageId)) {
continue;
}
validLayouts.push(layout);
}
}
return createIdMap(validLayouts, (layout) => ({
...layout,
title: layout.publishedRevision?.title,
}));
};
export const deleteLayoutSlot = async (id: string) => {
const db = useDatabase();
const slotIds: string[] = [];
const elementIds: string[] = [];
for (const consumer of await db.nitroElementSlot.findMany({
select: {
id: true,
elements: {
select: {
id: true,
},
},
},
where: {
parentLayoutSlotId: id,
},
})) {
slotIds.push(consumer.id);
for (const el of consumer.elements) {
elementIds.push(el.id);
}
}
await deleteElements(elementIds);
await db.nitroElementSlot.deleteMany({
where: {
id: {
in: slotIds,
},
},
});
await db.nitroLayoutSlot.delete({
where: {
id: id,
},
});
};