Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/db/entities/properties.db.server.ts
T

274 lines
6.8 KiB
TypeScript

import { PropertyType } from "~/application/enums/entities/PropertyType";
import { Colors } from "~/application/enums/shared/Colors";
import { defaultProperties } from "~/utils/helpers/PropertyHelper";
import { db } from "../../db.server";
export async function getProperty(id: string) {
return await db.property.findUnique({
where: {
id,
},
include: {
attributes: true,
options: {
orderBy: {
order: "asc",
},
},
formula: true,
},
});
}
export async function getEntityPropertyByName(entityId: string, name: string) {
return await db.property.findFirst({
where: {
entityId,
name,
},
include: {
attributes: true,
options: {
orderBy: {
order: "asc",
},
},
},
});
}
export async function createProperty(data: {
entityId: string;
name: string;
title: string;
type: PropertyType;
subtype: string | null;
order: number;
isDefault: boolean;
isRequired: boolean;
isHidden: boolean;
isDisplay: boolean;
isReadOnly: boolean;
canUpdate: boolean;
showInCreate: boolean;
formulaId: string | null;
tenantId: string | null;
}) {
if (data.name.includes(" ")) {
throw Error("Property names cannot contain spaces: " + data.name);
}
if (data.name.includes("-")) {
throw Error("Property names cannot contain '-': " + data.name);
}
return await db.property.create({
data,
});
}
export type CreatePropertyDto = {
name: string;
title: string;
type: PropertyType;
subtype: string | null;
isRequired?: boolean;
isDefault?: boolean;
isHidden?: boolean;
isDisplay?: boolean;
isReadOnly?: boolean;
canUpdate?: boolean;
showInCreate?: boolean;
formulaId?: string | null;
tenantId?: string | null;
options?: { order: number; value: string; name?: string; color?: Colors }[];
attributes?: {
name: string;
value: string;
}[];
};
export async function createProperties(entityId: string, fields: CreatePropertyDto[]) {
return await Promise.all(
fields.map(async (field, idx) => {
const property = await createProperty({
entityId,
order: defaultProperties.length + idx + 1,
name: field.name,
title: field.title,
type: field.type,
subtype: field.subtype ?? null,
isRequired: field.isRequired ?? true,
isDefault: field.isDefault ?? false,
isHidden: field.isHidden ?? false,
isDisplay: field.isDisplay ?? false,
isReadOnly: field.isReadOnly ?? false,
canUpdate: field.canUpdate ?? true,
showInCreate: field.showInCreate ?? true,
formulaId: field.formulaId ?? null,
tenantId: field.tenantId ?? null,
});
if (field.options) {
await updatePropertyOptions(
property.id,
field.options.map((option) => {
return {
order: option.order,
value: option.value,
name: option.name ?? null,
color: option.color,
};
})
);
}
if (field.attributes) {
await updatePropertyAttributes(property.id, field.attributes);
}
return property;
})
);
}
export async function updateProperty(
id: string,
data: {
name?: string;
title?: string;
type?: PropertyType;
subtype?: string | null;
order?: number;
isDefault?: boolean;
isRequired?: boolean;
isHidden?: boolean;
isDisplay?: boolean;
isReadOnly?: boolean;
canUpdate?: boolean;
showInCreate?: boolean;
formulaId?: string | null;
}
) {
const property = await db.property.update({
where: { id },
data,
});
return property;
}
type PropertyScope = {
id: string;
tenantId: string | null;
entityId: string;
};
type UpdatePropertyData = Parameters<typeof updateProperty>[1];
async function assertScopedProperty(scope: PropertyScope) {
const property = await getProperty(scope.id);
if (!property || property.tenantId !== scope.tenantId || property.entityId !== scope.entityId) {
throw Error("Property not found");
}
return property;
}
export async function getScopedProperty(scope: PropertyScope) {
const property = await getProperty(scope.id);
if (!property || property.tenantId !== scope.tenantId || property.entityId !== scope.entityId) {
return null;
}
return property;
}
export async function updateScopedProperty(scope: PropertyScope, data: UpdatePropertyData) {
const result = await db.property.updateMany({
where: scope,
data,
});
if (result.count !== 1) {
throw Error("Property not found");
}
return await assertScopedProperty(scope);
}
export async function updatePropertyOrder(id: string, order: number) {
return await db.property.update({
where: { id },
data: {
order,
},
});
}
export async function updateScopedPropertyOrder(scope: PropertyScope, order: number) {
const result = await db.property.updateMany({
where: scope,
data: {
order,
},
});
if (result.count !== 1) {
throw Error("Property not found");
}
}
export async function updatePropertyOptions(id: string, options: { order: number; value: string; name?: string | null; color?: Colors }[]) {
await db.propertyOption.deleteMany({
where: { propertyId: id },
});
await Promise.all(
options.map(async (option) => {
return await db.propertyOption.create({
data: {
propertyId: id,
order: option.order,
value: option.value,
name: option.name ?? null,
color: option.color,
},
});
})
);
}
export async function updateScopedPropertyOptions(scope: PropertyScope, options: { order: number; value: string; name?: string | null; color?: Colors }[]) {
await assertScopedProperty(scope);
await updatePropertyOptions(scope.id, options);
}
export async function updatePropertyAttributes(id: string, attributes: { name: string; value: string }[]) {
await db.propertyAttribute.deleteMany({
where: { propertyId: id },
});
await Promise.all(
attributes
.filter((f) => f.value !== undefined)
.map(async (attribute) => {
return await db.propertyAttribute.create({
data: {
propertyId: id,
name: attribute.name,
value: attribute.value,
},
});
})
);
}
export async function updateScopedPropertyAttributes(scope: PropertyScope, attributes: { name: string; value: string }[]) {
await assertScopedProperty(scope);
await updatePropertyAttributes(scope.id, attributes);
}
export async function deleteProperty(id: string) {
return await db.property.delete({
where: { id },
});
}
export async function deleteScopedProperty(scope: PropertyScope) {
const result = await db.property.deleteMany({
where: scope,
});
if (result.count !== 1) {
throw Error("Property not found");
}
}