Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/api/.server/EntitiesApi.ts
T

191 lines
7.3 KiB
TypeScript

import { PlanFeatureUsageDto } from "~/application/dtos/subscriptions/PlanFeatureUsageDto";
import { EntityWithDetails, findEntityByName, findEntityBySlug, getEntityByIdOrName, getEntityByPrefix } from "../../db/entities/entities.db.server";
import { getPlanFeatureUsage } from "../../services/.server/subscriptionService";
import { Entity } from "@toolctrl/db/prisma-browser";
import { Params } from "react-router";
import { getAbsoluteUrl } from "../../url.server";
import { adminPath, appPath } from "~/utils/app/CanonicalUrlUtils";
import { getHostRoutingContextFromRequest } from "~/utils/app/HostRouting.server";
import { isReservedTenantChildRouteSlug } from "~/utils/services/tenantService";
export namespace EntitiesApi {
export type GetEntityData = {
entity: EntityWithDetails;
featureUsageEntity?: PlanFeatureUsageDto | undefined;
};
export type Routes = {
list?: string;
new?: string;
overview?: string;
edit?: string;
publicUrl?: string;
import?: string;
export?: string;
group?: string;
};
export async function get({ entity, tenantId, userId }: { entity: { id?: string; name?: string }; tenantId?: string | null; userId?: string }) {
const item = await getEntityByIdOrName({ tenantId, ...entity });
const featureUsageEntity = tenantId ? await getPlanFeatureUsage(tenantId, item.name) : undefined;
await fillSystemProperties({ entity: item, tenantId, userId });
const data: GetEntityData = {
entity: item,
featureUsageEntity,
};
return data;
}
export async function validateEntity({
tenantId,
name,
slug,
order,
prefix,
entity,
}: {
tenantId: string | null;
name: string;
slug: string;
order: number | null;
prefix: string;
entity?: Entity;
}) {
const errors: string[] = [];
if (isReservedTenantChildRouteSlug(slug)) {
errors.push(`Reserved entity slug '${slug}' conflicts with a workspace route`);
}
if (!entity || entity?.name !== name) {
const existingName = await findEntityByName({ tenantId, name });
if (existingName) {
errors.push(`Existing entity with name '${name}': ${existingName.slug}`);
}
}
if (!entity || entity?.slug !== slug) {
const existingSlug = await findEntityBySlug(slug);
if (existingSlug) {
errors.push(`Existing entity with slug '${slug}': ${existingSlug.slug}`);
}
}
// if (order) {
// if (!entity || entity?.order !== order) {
// const existingOrder = await getEntityByOrder(order);
// if (existingOrder) {
// errors.push(`Existing entity with order '${order}': ${existingOrder.slug}`);
// }
// }
// }
if (!entity || entity?.prefix !== prefix) {
const existingPrefix = await getEntityByPrefix(prefix);
if (existingPrefix) {
errors.push(`Existing entity with prefix '${prefix}': ${existingPrefix.slug}`);
}
}
return errors;
}
export function getNoCodeRoutes({ request, params }: { request: Request; params: Params }): EntitiesApi.Routes {
const url = new URL(request.url);
const hostContext = getHostRoutingContextFromRequest(request);
const isAdminRequest = hostContext === "admin";
const isAppRequest = hostContext === "app";
const adminRoute = (path: string) => adminPath(path, { mode: "host-aware" });
const tenantRoute = (path: string) => appPath({ tenantSlug: params?.tenant ?? "", path, mode: "host-aware" });
if (params.group) {
if (isAdminRequest) {
const routes: EntitiesApi.Routes = {
list: adminRoute("entities/:entity/no-code/:entity"),
new: adminRoute("entities/:entity/no-code/:entity/new"),
overview: adminRoute("entities/:entity/no-code/:entity/:id"),
edit: adminRoute("entities/:entity/no-code/:entity/:id/edit"),
import: adminRoute("entities/:entity/no-code/:entity/import"),
export: adminRoute("entities/:entity/no-code/:entity/export"),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
group: adminRoute("entities/groups"),
};
return routes;
} else if (isAppRequest) {
const routes: EntitiesApi.Routes = {
list: tenantRoute(`g/${params.group}/:entity`),
new: tenantRoute(`g/${params.group}/:entity/new`),
overview: tenantRoute(`g/${params.group}/:entity/:id`),
edit: tenantRoute(`g/${params.group}/:entity/:id/edit`),
import: tenantRoute(`g/${params.group}/:entity/import`),
export: tenantRoute(`g/${params.group}/:entity/export`),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
group: tenantRoute(`g/${params.group}`),
};
return routes;
}
} else if (isAdminRequest && isPathOrChild(url.pathname, "/crm")) {
const routes: EntitiesApi.Routes = {
list: adminRoute("crm/:entity"),
new: adminRoute("crm/:entity/new"),
overview: adminRoute("crm/:entity/:id"),
edit: adminRoute("crm/:entity/:id/edit"),
import: adminRoute("crm/:entity/import"),
export: adminRoute("crm/:entity/export"),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
};
return routes;
} else if (isAdminRequest) {
const routes: EntitiesApi.Routes = {
list: adminRoute("entities/:entity/no-code/:entity"),
new: adminRoute("entities/:entity/no-code/:entity/new"),
overview: adminRoute("entities/:entity/no-code/:entity/:id"),
edit: adminRoute("entities/:entity/no-code/:entity/:id/edit"),
import: adminRoute("entities/:entity/no-code/:entity/import"),
export: adminRoute("entities/:entity/no-code/:entity/export"),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
};
return routes;
} else if (params?.tenant && isPathOrChild(url.pathname, `/${params.tenant}/crm`)) {
const routes: EntitiesApi.Routes = {
list: tenantRoute("crm/:entity"),
new: tenantRoute("crm/:entity/new"),
overview: tenantRoute("crm/:entity/:id"),
edit: tenantRoute("crm/:entity/:id/edit"),
import: tenantRoute("crm/:entity/import"),
export: tenantRoute("crm/:entity/export"),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
};
return routes;
}
const routes: EntitiesApi.Routes = {
list: tenantRoute(":entity"),
new: tenantRoute(":entity/new"),
overview: tenantRoute(":entity/:id"),
edit: tenantRoute(":entity/:id/edit"),
import: tenantRoute(":entity/import"),
export: tenantRoute(":entity/export"),
publicUrl: getAbsoluteUrl(request, `/public/:entity/:id`),
};
return routes;
}
export async function fillSystemProperties({
entity,
tenantId,
userId,
}: {
entity: EntityWithDetails;
tenantId: string | null | undefined;
userId: string | undefined;
}) {
// const userProp = entity.properties.find((f) => f.name === "user");
// if (userProp) {
// const users = await adminGetAllUsersNames();
// userProp.options = users.map((f) => ({
// value: f.email,
// name: f.email,
// })) as PropertyOption[];
// }
}
}
function isPathOrChild(pathname: string, prefix: string) {
return pathname === prefix || pathname.startsWith(`${prefix}/`);
}