rule engine and configration and fix booking for custoemr

This commit is contained in:
marshal
2026-06-01 23:15:11 +03:00
parent b9ca0b8a82
commit 452ebdbc0a
52 changed files with 3355 additions and 3358 deletions

View File

@@ -0,0 +1,185 @@
import type { RuleEngineResourceConfig } from "@/pages/ruleEngine/config/resources";
import type { RuleEngineRecord } from "@/types/rule-engine";
import { DataTableFooter } from "@edr/ui-common";
import type { Table } from "@edr/ui-common";
import RuleEngineRecordActions from "./RuleEngineRecordActions";
import { cardInitials, resolveCardPresentation } from "./ruleEngineCardMeta";
import { formatCell } from "./ruleEngineFormat";
import { ruleEngineCard } from "./ruleEngineStyles";
export interface RuleEngineCardGridProps {
config: RuleEngineResourceConfig;
rows: RuleEngineRecord[];
status: "loading" | "error" | "success";
emptyMessage: string;
itemLabel: string;
table: Table<RuleEngineRecord>;
pagination: {
pageIndex: number;
pageSize: number;
pageCount: number;
totalCount: number;
};
onEdit: (record: RuleEngineRecord) => void;
onDelete: (record: RuleEngineRecord) => void;
onViewChain?: () => void;
onSubmitRate?: (id: string) => void;
onApproveRate?: (record: RuleEngineRecord) => void;
}
const RuleEngineCardGrid = ({
config,
rows,
status,
emptyMessage,
itemLabel,
table,
pagination,
onEdit,
onDelete,
onViewChain,
onSubmitRate,
onApproveRate,
}: RuleEngineCardGridProps) => {
const presentation = resolveCardPresentation(config);
if (status === "error") {
return (
<div className="flex flex-col items-center justify-center px-6 py-16 text-center">
<p className="text-sm font-medium text-foreground">Failed to load data</p>
<p className="mt-1 text-sm text-muted-foreground">
Please refresh the page or try again later.
</p>
</div>
);
}
if (status === "loading") {
return (
<div className="grid grid-cols-1 gap-3 p-4 sm:grid-cols-2 lg:grid-cols-3 xl:gap-4">
{Array.from({ length: 6 }).map((_, index) => (
<div key={index} className={ruleEngineCard.skeleton}>
<div className="flex gap-3">
<div className="h-10 w-10 rounded-md bg-muted" />
<div className="flex-1 space-y-2">
<div className="h-4 w-2/3 rounded-sm bg-muted" />
<div className="h-3 w-1/3 rounded-sm bg-muted" />
</div>
</div>
<div className="mt-4 space-y-2">
<div className="h-3 w-full rounded-sm bg-muted" />
<div className="h-3 w-4/5 rounded-sm bg-muted" />
</div>
</div>
))}
</div>
);
}
if (status === "success" && rows.length === 0) {
return (
<div className="flex flex-col items-center justify-center px-6 py-16 text-center">
<p className="text-sm font-medium text-foreground">{emptyMessage}</p>
<p className="mt-1 text-sm text-muted-foreground">
Try adjusting your search or add a new record.
</p>
</div>
);
}
return (
<>
<div className="grid grid-cols-1 gap-3 p-4 sm:grid-cols-2 lg:grid-cols-3 xl:gap-4">
{rows.map((record) => {
const title = String(record[presentation.titleKey] ?? "Untitled");
const subtitle = presentation.subtitleKey
? String(record[presentation.subtitleKey] ?? "")
: "";
const code = presentation.codeKey
? String(record[presentation.codeKey] ?? "")
: "";
const statusValue = presentation.statusKey
? record[presentation.statusKey]
: undefined;
return (
<article key={record.id} className={ruleEngineCard.article}>
<div className={ruleEngineCard.header}>
<div className="flex items-start gap-3">
<div className={ruleEngineCard.avatar} aria-hidden>
{cardInitials(title)}
</div>
<div className="min-w-0 flex-1">
<div className="flex flex-wrap items-center gap-2">
<h3 className={ruleEngineCard.title}>{title}</h3>
{presentation.statusKey
? formatCell(statusValue, "activeBadge")
: null}
</div>
{(code || subtitle) && (
<div className="mt-1.5 flex flex-wrap items-center gap-2">
{code ? formatCell(code, "code") : null}
{subtitle ? (
<span className={ruleEngineCard.meta}>
{presentation.subtitleKey === "stepOrder"
? `Step ${subtitle}`
: subtitle}
</span>
) : null}
</div>
)}
</div>
</div>
</div>
{presentation.detailColumns.length > 0 ? (
<dl className="grid flex-1 gap-x-4 gap-y-3 px-4 py-3.5 sm:grid-cols-2">
{presentation.detailColumns.map((col) => (
<div key={col.id} className="min-w-0">
<dt className={ruleEngineCard.detailLabel}>{col.header}</dt>
<dd className={ruleEngineCard.detailValue}>
{formatCell(record[col.accessorKey], col.format)}
</dd>
</div>
))}
</dl>
) : (
<div className="flex-1 px-4 py-2" />
)}
<div className={ruleEngineCard.footer}>
<RuleEngineRecordActions
record={record}
config={config}
layout="compact"
onEdit={onEdit}
onDelete={onDelete}
onViewChain={onViewChain}
onSubmitRate={onSubmitRate}
onApproveRate={onApproveRate}
/>
</div>
</article>
);
})}
</div>
<div className="border-t border-border bg-card">
<DataTableFooter
table={table}
pagination={pagination}
options={{
labels: {
showing: "Showing",
ofLabel: "of",
items: itemLabel,
},
}}
/>
</div>
</>
);
};
export default RuleEngineCardGrid;