259 lines
7.3 KiB
TypeScript
259 lines
7.3 KiB
TypeScript
import { EntityRelationship } from "@toolctrl/db/prisma-browser";
|
|
import { db } from "../../db.server";
|
|
import { EntityViewWithDetails } from "./entityViews.db.server";
|
|
import EntityViewModelHelper from "~/utils/helpers/models/EntityViewModelHelper";
|
|
import EntityModelHelper from "~/utils/helpers/models/EntityModelHelper";
|
|
|
|
export type EntityRelationshipWithDetails = EntityRelationship & {
|
|
parent: { id: string; name: string; title: string; titlePlural: string; slug: string; onEdit: string | null };
|
|
child: { id: string; name: string; title: string; titlePlural: string; slug: string; onEdit: string | null };
|
|
childEntityView: EntityViewWithDetails | null;
|
|
parentEntityView: EntityViewWithDetails | null;
|
|
};
|
|
|
|
export type EntityRelationshipWithCount = EntityRelationshipWithDetails & {
|
|
_count: { rows: number };
|
|
};
|
|
|
|
export async function getAllEntityRelationships(): Promise<EntityRelationshipWithDetails[]> {
|
|
return await db.entityRelationship.findMany({
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
},
|
|
});
|
|
}
|
|
export async function findEntityRelationship({
|
|
parentId,
|
|
childId,
|
|
title,
|
|
notIn,
|
|
}: {
|
|
parentId: string;
|
|
childId: string;
|
|
title: string | null;
|
|
notIn?: string[];
|
|
}): Promise<EntityRelationshipWithCount | null> {
|
|
return await db.entityRelationship.findFirst({
|
|
where: {
|
|
OR: [
|
|
{ parentId, childId },
|
|
{ parentId: childId, childId: parentId },
|
|
],
|
|
title,
|
|
id: {
|
|
notIn,
|
|
},
|
|
},
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
_count: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function getEntityRelationships(entityId: string): Promise<EntityRelationshipWithDetails[]> {
|
|
return await db.entityRelationship.findMany({
|
|
where: {
|
|
OR: [
|
|
{
|
|
parentId: entityId,
|
|
},
|
|
{
|
|
childId: entityId,
|
|
},
|
|
],
|
|
},
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
},
|
|
orderBy: [{ order: "asc" }],
|
|
});
|
|
}
|
|
|
|
export async function getEntityRelationshipsWithCount(entityId: string): Promise<EntityRelationshipWithCount[]> {
|
|
return await db.entityRelationship.findMany({
|
|
where: {
|
|
OR: [{ parentId: entityId }, { childId: entityId }],
|
|
},
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
_count: true,
|
|
},
|
|
orderBy: [{ order: "asc" }],
|
|
});
|
|
}
|
|
|
|
export async function getEntitiesRelationship({
|
|
parentEntityId,
|
|
childEntityId,
|
|
}: {
|
|
parentEntityId: string;
|
|
childEntityId: string;
|
|
}): Promise<EntityRelationshipWithDetails | null> {
|
|
return await db.entityRelationship.findFirst({
|
|
where: {
|
|
parentId: parentEntityId,
|
|
childId: childEntityId,
|
|
},
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
},
|
|
orderBy: [{ order: "asc" }],
|
|
});
|
|
}
|
|
|
|
export async function getEntityRelationship(id: string): Promise<EntityRelationshipWithCount | null> {
|
|
return await db.entityRelationship.findUnique({
|
|
where: {
|
|
id,
|
|
},
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
_count: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
type EntityRelationshipScope = {
|
|
id: string;
|
|
entityId: string;
|
|
};
|
|
|
|
function relationshipScopeWhere(scope: EntityRelationshipScope) {
|
|
return {
|
|
id: scope.id,
|
|
OR: [{ parentId: scope.entityId }, { childId: scope.entityId }],
|
|
};
|
|
}
|
|
|
|
export async function getScopedEntityRelationship(scope: EntityRelationshipScope): Promise<EntityRelationshipWithCount | null> {
|
|
return await db.entityRelationship.findFirst({
|
|
where: relationshipScopeWhere(scope),
|
|
include: {
|
|
parent: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
child: { select: EntityModelHelper.selectEntityWithoutIcon },
|
|
childEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
parentEntityView: { include: EntityViewModelHelper.includeDetails },
|
|
_count: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function createEntityRelationship({
|
|
parentId,
|
|
childId,
|
|
order,
|
|
title,
|
|
type,
|
|
required,
|
|
cascade,
|
|
readOnly,
|
|
hiddenIfEmpty,
|
|
childEntityViewId,
|
|
parentEntityViewId,
|
|
}: {
|
|
parentId: string;
|
|
childId: string;
|
|
order: number;
|
|
title: string | null;
|
|
type: string;
|
|
required: boolean;
|
|
cascade: boolean;
|
|
readOnly: boolean;
|
|
hiddenIfEmpty: boolean;
|
|
childEntityViewId: string | null;
|
|
parentEntityViewId: string | null;
|
|
}) {
|
|
return await db.entityRelationship.create({
|
|
data: {
|
|
parentId,
|
|
childId,
|
|
order,
|
|
title,
|
|
type,
|
|
required,
|
|
cascade,
|
|
readOnly,
|
|
hiddenIfEmpty,
|
|
childEntityViewId,
|
|
parentEntityViewId,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function updateEntityRelationship(
|
|
id: string,
|
|
data: {
|
|
parentId?: string;
|
|
childId?: string;
|
|
order?: number;
|
|
title?: string | null;
|
|
type?: string;
|
|
required?: boolean;
|
|
cascade?: boolean;
|
|
readOnly?: boolean;
|
|
hiddenIfEmpty?: boolean;
|
|
childEntityViewId?: string | null;
|
|
parentEntityViewId?: string | null;
|
|
}
|
|
) {
|
|
return await db.entityRelationship.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
...data,
|
|
},
|
|
});
|
|
}
|
|
|
|
type UpdateEntityRelationshipData = Parameters<typeof updateEntityRelationship>[1];
|
|
|
|
export async function updateScopedEntityRelationship(scope: EntityRelationshipScope, data: UpdateEntityRelationshipData) {
|
|
const result = await db.entityRelationship.updateMany({
|
|
where: relationshipScopeWhere(scope),
|
|
data: {
|
|
...data,
|
|
},
|
|
});
|
|
if (result.count !== 1) {
|
|
throw Error("Relationship not found");
|
|
}
|
|
return await getScopedEntityRelationship(scope);
|
|
}
|
|
|
|
export async function deleteEntityRelationship(id: string) {
|
|
return await db.entityRelationship.delete({
|
|
where: {
|
|
id,
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function deleteScopedEntityRelationship(scope: EntityRelationshipScope) {
|
|
const result = await db.entityRelationship.deleteMany({
|
|
where: relationshipScopeWhere(scope),
|
|
});
|
|
if (result.count !== 1) {
|
|
throw Error("Relationship not found");
|
|
}
|
|
}
|