fix: type error and other fixes

This commit is contained in:
Nathnael
2026-06-23 13:14:06 +00:00
parent cdfe7c1f5b
commit cbbad02b29
18 changed files with 116 additions and 179 deletions

View File

@@ -282,6 +282,7 @@ export class CompaniesService {
async findCompanyById(id: string): Promise<Company> { async findCompanyById(id: string): Promise<Company> {
const company = await this.companiesRepo.findById(id); const company = await this.companiesRepo.findById(id);
if (!company) throw new NotFoundException(`Company ${id} not found`); if (!company) throw new NotFoundException(`Company ${id} not found`);
company.companyProfiles = await this.companyProfilesRepo.findByCompanyId(id);
return company; return company;
} }

View File

@@ -2152,6 +2152,7 @@ export class TrainSchedulingService {
weightTons: roundTons(Number(sb.booking?.cargoTotalWeightVgm ?? 0)), weightTons: roundTons(Number(sb.booking?.cargoTotalWeightVgm ?? 0)),
status: sb.booking?.status ?? null, status: sb.booking?.status ?? null,
schedulingStatus: sb.booking?.schedulingStatus ?? null, schedulingStatus: sb.booking?.schedulingStatus ?? null,
freightType: sb.booking?.freightType ?? null,
})) ?? [], })) ?? [],
}; };
} }

View File

@@ -138,6 +138,8 @@ export interface BookingDetailView {
priorityScore: number; priorityScore: number;
cargoTotalWeightVgm: number; cargoTotalWeightVgm: number;
pnrCode?: string | null; pnrCode?: string | null;
consolidationPartnerId?: string | null;
consolidationPartner?: (BookingNamedRefView & { reference?: string }) | null;
/** End of the pay window once the booking is SELECTED_FOR_BATCH. */ /** End of the pay window once the booking is SELECTED_FOR_BATCH. */
paymentDeadline?: string | null; paymentDeadline?: string | null;
createdAt: string; createdAt: string;

View File

@@ -11,7 +11,7 @@ import {
import type { TrainScheduleDetail } from "@/types/trainScheduling"; import type { TrainScheduleDetail } from "@/types/trainScheduling";
import { freightBrand } from "@/theme/freight-brand"; import { freightBrand } from "@/theme/freight-brand";
type Wagon = TrainScheduleDetail["trainSet"]["wagons"][number]; type Wagon = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
export interface BookingDetailData { export interface BookingDetailData {
bookingId: string; bookingId: string;

View File

@@ -11,7 +11,7 @@ import {
import type { TrainScheduleDetail } from "@/types/trainScheduling"; import type { TrainScheduleDetail } from "@/types/trainScheduling";
import { freightBrand } from "@/theme/freight-brand"; import { freightBrand } from "@/theme/freight-brand";
type Wagon = TrainScheduleDetail["trainSet"]["wagons"][number]; type Wagon = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
type Locomotive = NonNullable<TrainScheduleDetail["trainSet"]>["locomotive"]; type Locomotive = NonNullable<TrainScheduleDetail["trainSet"]>["locomotive"];
interface InteractiveTrainConsistProps { interface InteractiveTrainConsistProps {

View File

@@ -1,7 +1,7 @@
import { Button, Group, Modal, Stack, Text, Badge } from "@mantine/core"; import { Button, Group, Modal, Stack, Text, Badge } from "@mantine/core";
import type { TrainScheduleDetail } from "@/types/trainScheduling"; import type { TrainScheduleDetail } from "@/types/trainScheduling";
type WagonWithAllocation = TrainScheduleDetail["trainSet"]["wagons"][number]; type WagonWithAllocation = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
interface RemoveBookingModalProps { interface RemoveBookingModalProps {
opened: boolean; opened: boolean;
@@ -21,7 +21,6 @@ export const RemoveBookingModal = ({
if (!wagon || !wagon.allocations?.[0]) return null; if (!wagon || !wagon.allocations?.[0]) return null;
const allocation = wagon.allocations[0]; const allocation = wagon.allocations[0];
const booking = allocation.booking;
return ( return (
<Modal opened={opened} onClose={onClose} title="Confirm Booking Removal" centered> <Modal opened={opened} onClose={onClose} title="Confirm Booking Removal" centered>
@@ -32,12 +31,12 @@ export const RemoveBookingModal = ({
</Text> </Text>
<Stack gap={4}> <Stack gap={4}>
<Text size="sm"> <Text size="sm">
<strong>Reference:</strong> {booking?.reference || "N/A"} <strong>Reference:</strong> {allocation.bookingReference || "N/A"}
</Text> </Text>
<Text size="sm"> <Text size="sm">
<strong>Freight Type:</strong>{" "} <strong>Freight Type:</strong>{" "}
<Badge size="sm" variant="light"> <Badge size="sm" variant="light">
{booking?.freightType || "N/A"} {allocation.loadType || "N/A"}
</Badge> </Badge>
</Text> </Text>
<Text size="sm"> <Text size="sm">

View File

@@ -10,7 +10,7 @@ import { useMutation } from "@tanstack/react-query";
import { api } from "@/services/api"; import { api } from "@/services/api";
import { freightBrand } from "@/theme/freight-brand"; import { freightBrand } from "@/theme/freight-brand";
type Wagon = TrainScheduleDetail["trainSet"]["wagons"][number]; type Wagon = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
interface TrainConsistViewProps { interface TrainConsistViewProps {
scheduleDetail: TrainScheduleDetail; scheduleDetail: TrainScheduleDetail;
@@ -103,9 +103,9 @@ export const TrainConsistView = ({
<Stack gap="md" style={{ width: "100%" }}> <Stack gap="md" style={{ width: "100%" }}>
<TrainStatsBar <TrainStatsBar
weightUsed={weightUsed} weightUsed={weightUsed}
weightMax={scheduleDetail.locomotive?.maxWeightTons ?? trainSet?.locomotive?.maxPullWeightTons ?? null} weightMax={trainSet?.locomotive?.maxPullWeightTons ?? null}
lengthUsed={lengthUsed} lengthUsed={lengthUsed}
lengthMax={scheduleDetail.locomotive?.maxLengthMeters ?? trainSet?.locomotive?.maxTrainLengthMeters ?? null} lengthMax={trainSet?.locomotive?.maxTrainLengthMeters ?? null}
wagonCount={wagons.length} wagonCount={wagons.length}
wagonMax={maxWagons} wagonMax={maxWagons}
/> />

View File

@@ -12,7 +12,7 @@ import type { TrainScheduleDetail } from "@/types/trainScheduling";
import { ContainerNumberInput } from "./ContainerNumberInput"; import { ContainerNumberInput } from "./ContainerNumberInput";
import { freightBrand } from "@/theme/freight-brand"; import { freightBrand } from "@/theme/freight-brand";
type Wagon = TrainScheduleDetail["trainSet"]["wagons"][number]; type Wagon = NonNullable<TrainScheduleDetail["trainSet"]>["wagons"][number];
interface WagonCardProps { interface WagonCardProps {
wagon: Wagon; wagon: Wagon;

View File

@@ -1,11 +1,12 @@
import { useMemo } from "react"; import { DataTable, type ColumnDef } from "@edr/ui-common";
import { ActionIcon, Badge, Button, Group, Text, Tooltip } from "@mantine/core"; import { ActionIcon, Badge, Button, Group, Text, Tooltip } from "@mantine/core";
import { ArrowRightLeft, ClipboardList, Coins, History } from "lucide-react"; import { ArrowRightLeft, ClipboardList, Coins, History } from "lucide-react";
import { DataTable, type ColumnDef } from "@edr/ui-common"; import { useMemo } from "react";
import type { import {
InventoryAction, INVENTORY_NEXT_ACTION,
WarehouseInventoryItem, type InventoryAction,
type WarehouseInventoryItem,
} from "@/types/warehouse"; } from "@/types/warehouse";
import { InventoryStatusBadge } from "./badges"; import { InventoryStatusBadge } from "./badges";
import { formatDate, formatNumber, humanizeEnum } from "./options"; import { formatDate, formatNumber, humanizeEnum } from "./options";
@@ -54,12 +55,6 @@ export function WarehouseInventoryTable({
onHistory, onHistory,
onInspect, onInspect,
onFeePreview, onFeePreview,
onLastMile,
selectedIds,
onToggleSelect,
onToggleSelectAll,
allSelected,
someSelected,
}: WarehouseInventoryTableProps) { }: WarehouseInventoryTableProps) {
const columns = useMemo<ColumnDef<WarehouseInventoryItem>[]>( const columns = useMemo<ColumnDef<WarehouseInventoryItem>[]>(
() => [ () => [

View File

@@ -662,7 +662,7 @@ export default function NewBookingPage() {
placeholder="Select bulk cargo type" placeholder="Select bulk cargo type"
data={cargoData} data={cargoData}
value={cargoTypeId} value={cargoTypeId}
onChange={setCargoTypeId} onChange={(value) => setCargoTypeId(value as string | null)}
searchable searchable
disabled={isLoading} disabled={isLoading}
/> />

View File

@@ -93,7 +93,7 @@ const OverviewPage = () => {
const getTabBadge = (tab: (typeof TAB_ITEMS)[number]) => { const getTabBadge = (tab: (typeof TAB_ITEMS)[number]) => {
if (!summary?.kpis) return 0; if (!summary?.kpis) return 0;
const group = summary.kpis[tab.kpiKey] as Record<string, number>; const group = summary.kpis[tab.kpiKey] as unknown as Record<string, number>;
return group[tab.metricKey] ?? 0; return group[tab.metricKey] ?? 0;
}; };

View File

@@ -1,49 +1,49 @@
import { FormEvent, ReactNode, useMemo, useState } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query'; import { useMutation, useQuery } from '@tanstack/react-query';
import { Edit, Eye, Plus, Search, Trash2 } from 'lucide-react'; import { Edit, Eye, Plus, Search, Trash2 } from 'lucide-react';
import { FormEvent, ReactNode, useMemo, useState } from 'react';
import { api } from '@/services/api'; import { api } from '@/services/api';
import { import {
ActionIcon, ActionIcon,
Badge as MantineBadge, Box,
Box, Group,
Button as MantineButton, Badge as MantineBadge,
Group, Button as MantineButton,
Modal, Select as MantineSelect,
NumberInput, Table as MantineTable,
Pagination, Modal,
Paper, NumberInput,
ScrollArea, Pagination,
Select as MantineSelect, Paper,
SimpleGrid, ScrollArea,
Stack, SimpleGrid,
Table as MantineTable, Stack,
Text, Text,
TextInput, TextInput,
Title, Title,
} from '@mantine/core'; } from '@mantine/core';
import { DeliverCargoDialog } from '@/components/cargoes/DeliverCargoDialog';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
DialogFooter, DialogFooter,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@edr/ui-common';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import type { Cargo } from '@/services/cargoService'; import type { Cargo } from '@/services/cargoService';
import { DeliverCargoDialog } from '@/components/cargoes/DeliverCargoDialog';
import type { Container } from '@/services/containerService'; import type { Container } from '@/services/containerService';
import type { Locomotive } from '@/services/locomotives.service'; import type { Locomotive } from '@/services/locomotives.service';
import type { Train } from '@/services/trains.service'; import type { Train } from '@/services/trains.service';
import type { Wagon } from '@/services/wagon.service';
import type { WagonType } from '@/services/wagon-types.service'; import type { WagonType } from '@/services/wagon-types.service';
import type { Wagon } from '@/services/wagon.service';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@edr/ui-common';
type FormValue = string | number | boolean | string[]; type FormValue = string | number | boolean | string[];
@@ -331,7 +331,7 @@ function FleetCrudPage<T extends { id: string }>({
<TableRow key={item.id}> <TableRow key={item.id}>
{columns.map((column) => ( {columns.map((column) => (
<TableCell key={String(column.key)}> <TableCell key={String(column.key)}>
{column.render ? column.render(item) : String((item as Record<string, unknown>)[column.key] ?? '-')} {column.render ? column.render(item) : String((item as Record<string, unknown>)[String(column.key)] ?? '-')}
</TableCell> </TableCell>
))} ))}
<TableCell> <TableCell>
@@ -410,7 +410,7 @@ function FleetCrudPage<T extends { id: string }>({
...current, ...current,
[field.key]: selectedValue, [field.key]: selectedValue,
...(field.onValueChange?.(selectedValue, current) ?? {}), ...(field.onValueChange?.(selectedValue, current) ?? {}),
})) }) as Record<string, FormValue>)
} }
> >
<SelectTrigger id={field.key}> <SelectTrigger id={field.key}>
@@ -480,12 +480,6 @@ function FleetCrudPage<T extends { id: string }>({
const statusBadge = (status?: string) => <Badge variant="outline">{status ?? '-'}</Badge>; const statusBadge = (status?: string) => <Badge variant="outline">{status ?? '-'}</Badge>;
const activeBadge = (isActive?: boolean) => (
<Badge variant={isActive === false ? 'secondary' : 'outline'}>
{isActive === false ? 'Inactive' : 'Active'}
</Badge>
);
const optionLabel = (options: { value: string; label: string }[], value?: string | null) => const optionLabel = (options: { value: string; label: string }[], value?: string | null) =>
options.find((option) => option.value === value)?.label ?? value ?? '-'; options.find((option) => option.value === value)?.label ?? value ?? '-';

View File

@@ -1,19 +1,10 @@
import type { ColumnDef } from "@edr/ui-common"; import type { ColumnDef } from "@edr/ui-common";
import { Box, Button, Card, Group, Modal, Select, Stack, Text } from "@mantine/core"; import { Box, Button, Card, Container, Group, Modal, Select, Stack, Text, Title } from "@mantine/core";
import { useMutation, useQuery } from "@tanstack/react-query"; import { useMutation, useQuery } from "@tanstack/react-query";
import { api } from "@/services/api"; import { api } from "@/services/api";
import { import Breadcrumbs from "@/components/ui/Breadcrumbs";
Archive, import { Plus } from "lucide-react";
Circle,
CircleCheck,
CircleSlash,
Layers,
Link2,
Plus,
Wrench,
type LucideIcon,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { Navigate, useLocation } from "react-router-dom"; import { Navigate, useLocation } from "react-router-dom";
@@ -23,37 +14,20 @@ import FleetRecordActions from "@/components/fleet/FleetRecordActions";
import FleetToolbar from "@/components/fleet/FleetToolbar"; import FleetToolbar from "@/components/fleet/FleetToolbar";
import { formatFleetCell, registerFleetOptionLabels } from "@/components/fleet/fleetFormat"; import { formatFleetCell, registerFleetOptionLabels } from "@/components/fleet/fleetFormat";
import { useFleetViewMode } from "@/components/fleet/useFleetViewMode"; import { useFleetViewMode } from "@/components/fleet/useFleetViewMode";
import { KpiStrip, PageContainer, PageHeader } from "@/components/page";
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles"; import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { import {
FLEET_SELECT_NONE, FLEET_SELECT_NONE,
getFleetResource, getFleetResource,
getFleetSlugFromPath, getFleetSlugFromPath,
type FleetFormFieldDef, type FleetFormFieldDef,
type FleetResourceSlug, type FleetResourceSlug,
} from "@/pages/fleet/config/resources"; } from "@/pages/fleet/config/resources";
import type { FleetListFilters, FleetRecord } from "@/services/fleet/fleet.service"; import type { FleetListFilters, FleetRecord } from "@/services/fleet/fleet.service";
import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common"; import { DataTable, DataTableFooter, usePagination } from "@edr/ui-common";
const DEFAULT_SLUG: FleetResourceSlug = "locomotives"; const DEFAULT_SLUG: FleetResourceSlug = "locomotives";
const FLEET_STATUS_META: Record<
string,
{ label: string; icon: LucideIcon; color: string }
> = {
AVAILABLE: { label: "Available", icon: CircleCheck, color: "edr-green" },
ASSIGNED: { label: "Assigned", icon: Link2, color: "blue" },
MAINTENANCE: { label: "Maintenance", icon: Wrench, color: "yellow" },
OUT_OF_SERVICE: { label: "Out of service", icon: CircleSlash, color: "red" },
RETIRED: { label: "Retired", icon: Archive, color: "gray" },
};
const humanizeStatus = (status: string) => {
const text = status.replace(/_/g, " ").toLowerCase();
return text.charAt(0).toUpperCase() + text.slice(1);
};
const FleetResourcePage = () => { const FleetResourcePage = () => {
const location = useLocation(); const location = useLocation();
const slug = getFleetSlugFromPath(location.pathname) ?? DEFAULT_SLUG; const slug = getFleetSlugFromPath(location.pathname) ?? DEFAULT_SLUG;
@@ -113,6 +87,9 @@ const FleetResourcePage = () => {
const { data: yards = [], isLoading: yardsLoading } = useQuery( const { data: yards = [], isLoading: yardsLoading } = useQuery(
api.routes.yards.queryOptions(), api.routes.yards.queryOptions(),
); );
const { data: drivers = [] } = useQuery(
api.fleet.list.queryOptions({ input: { slug: "drivers" } }),
);
useEffect(() => { useEffect(() => {
setPagination((prev) => ({ pageIndex: 0, pageSize: prev.pageSize })); setPagination((prev) => ({ pageIndex: 0, pageSize: prev.pageSize }));
@@ -301,39 +278,6 @@ const FleetResourcePage = () => {
const tableStatus = isLoading ? "loading" : isError ? "error" : "success"; const tableStatus = isLoading ? "loading" : isError ? "error" : "success";
const kpiItems = useMemo(() => {
const items = [
{
label: `Total ${config?.label.toLowerCase() ?? ""}`,
value: allRows.length,
icon: Layers,
color: "edr-green",
},
];
if (hasStatusColumn) {
const counts = new Map<string, number>();
for (const row of allRows) {
const status = String(
(row as unknown as Record<string, unknown>).status ?? "",
);
if (status) counts.set(status, (counts.get(status) ?? 0) + 1);
}
const top = [...counts.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 4);
for (const [status, count] of top) {
const meta = FLEET_STATUS_META[status];
items.push({
label: meta?.label ?? humanizeStatus(status),
value: count,
icon: meta?.icon ?? Circle,
color: meta?.color ?? "gray",
});
}
}
return items.slice(0, 5);
}, [allRows, hasStatusColumn, config?.label]);
if (!config) { if (!config) {
return <Navigate to="/dashboard/locomotives" replace />; return <Navigate to="/dashboard/locomotives" replace />;
} }
@@ -376,7 +320,7 @@ const FleetResourcePage = () => {
const handleAssignDriver = async () => { const handleAssignDriver = async () => {
if (!assigningDriver || !("id" in assigningDriver) || !selectedDriver) return; if (!assigningDriver || !("id" in assigningDriver) || !selectedDriver) return;
try { try {
const selectedDriverRecord = (drivers as Array<Record<string, unknown>>).find( const selectedDriverRecord = (drivers as unknown as Array<Record<string, unknown>>).find(
(d) => String(d.id) === selectedDriver (d) => String(d.id) === selectedDriver
); );
if (!selectedDriverRecord) return; if (!selectedDriverRecord) return;
@@ -384,6 +328,7 @@ const FleetResourcePage = () => {
const driverName = `${selectedDriverRecord.firstName} ${selectedDriverRecord.lastName}`; const driverName = `${selectedDriverRecord.firstName} ${selectedDriverRecord.lastName}`;
await update.mutateAsync({ await update.mutateAsync({
slug,
id: String(assigningDriver.id), id: String(assigningDriver.id),
data: { data: {
assignedDriverId: selectedDriver, assignedDriverId: selectedDriver,
@@ -608,7 +553,7 @@ const FleetResourcePage = () => {
clearable clearable
value={selectedDriver} value={selectedDriver}
onChange={(value) => setSelectedDriver(value || "")} onChange={(value) => setSelectedDriver(value || "")}
data={(drivers as Array<Record<string, unknown>>).map((driver) => ({ data={(drivers as unknown as Array<Record<string, unknown>>).map((driver) => ({
value: String(driver.id || ""), value: String(driver.id || ""),
label: `${driver.firstName} ${driver.lastName} (${driver.licenseNumber})`, label: `${driver.firstName} ${driver.lastName} (${driver.licenseNumber})`,
}))} }))}

View File

@@ -1,58 +1,56 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { Navigate, useLocation, useParams } from "react-router-dom";
import { useAuth } from "@/auth/useAuth"; import { useAuth } from "@/auth/useAuth";
import { canAccessRuleEngineResource } from "@/lib/permissions"; import { canAccessRuleEngineResource } from "@/lib/permissions";
import type { ColumnDef } from "@edr/ui-common"; import type { ColumnDef } from "@edr/ui-common";
import { import {
Box, Box,
Card, Button,
Button, Card,
Modal, Group,
Stack, List,
Group, Loader,
Text, Modal,
List, Stack,
Loader, Text,
} from "@mantine/core"; } from "@mantine/core";
import { Plus } from "lucide-react"; import { Plus } from "lucide-react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Navigate, useLocation, useParams } from "react-router-dom";
import { PageContainer, PageHeader } from "@/components/page"; import { PageContainer, PageHeader } from "@/components/page";
import ManageRuleEngineOrderDialog from "@/components/ruleEngine/ManageRuleEngineOrderDialog";
import RuleEngineCardGrid from "@/components/ruleEngine/RuleEngineCardGrid"; import RuleEngineCardGrid from "@/components/ruleEngine/RuleEngineCardGrid";
import RuleEngineFormDialog from "@/components/ruleEngine/RuleEngineFormDialog"; import RuleEngineFormDialog from "@/components/ruleEngine/RuleEngineFormDialog";
import ManageRuleEngineOrderDialog from "@/components/ruleEngine/ManageRuleEngineOrderDialog";
import RuleEngineOrderControls from "@/components/ruleEngine/RuleEngineOrderControls"; import RuleEngineOrderControls from "@/components/ruleEngine/RuleEngineOrderControls";
import RuleEngineRecordActions from "@/components/ruleEngine/RuleEngineRecordActions"; import RuleEngineRecordActions from "@/components/ruleEngine/RuleEngineRecordActions";
import { getOrderItemLabel } from "@/components/ruleEngine/ruleEngineOrder.utils";
import RuleEngineToolbar from "@/components/ruleEngine/RuleEngineToolbar"; import RuleEngineToolbar from "@/components/ruleEngine/RuleEngineToolbar";
import { formatCell } from "@/components/ruleEngine/ruleEngineFormat"; import { formatCell } from "@/components/ruleEngine/ruleEngineFormat";
import { getOrderItemLabel } from "@/components/ruleEngine/ruleEngineOrder.utils";
import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles"; import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles";
import { useRuleEngineViewMode } from "@/components/ruleEngine/useRuleEngineViewMode"; import { useRuleEngineViewMode } from "@/components/ruleEngine/useRuleEngineViewMode";
import { import {
DEFAULT_CONFIGURATION_SLUG, useApprovalChain,
DEFAULT_RULES_SLUG, useCargoTypeParentOptions,
RULE_ENGINE_CATEGORY_BASE_PATH, useContainerTypeOptions,
RULE_ENGINE_SELECT_NONE, useLiveRateOptions,
getRuleEngineResource, useRateWorkflow,
type RuleEngineNavCategory, useRuleEngineList,
} from "@/pages/ruleEngine/config/resources"; useRuleEngineMutations,
import { useRuleEngineOrderList,
useApprovalChain, useRuleEngineOrderMutations,
useCargoTypeParentOptions,
useContainerTypeOptions,
useLiveRateOptions,
useRateWorkflow,
useRuleEngineList,
useRuleEngineMutations,
useRuleEngineOrderList,
useRuleEngineOrderMutations,
} from "@/hooks/rule-engine/useRuleEngine"; } from "@/hooks/rule-engine/useRuleEngine";
import {
DEFAULT_CONFIGURATION_SLUG,
DEFAULT_RULES_SLUG,
RULE_ENGINE_CATEGORY_BASE_PATH,
RULE_ENGINE_SELECT_NONE,
getRuleEngineResource,
type RuleEngineNavCategory,
} from "@/pages/ruleEngine/config/resources";
import type { RuleEngineRecord } from "@/types/rule-engine"; import type { RuleEngineRecord } from "@/types/rule-engine";
import { import {
DataTable, DataTable,
DataTableFooter, DataTableFooter,
getCoreRowModel, usePagination,
usePagination,
useReactTable,
} from "@edr/ui-common"; } from "@edr/ui-common";
const pathCategory = (pathname: string): RuleEngineNavCategory | undefined => { const pathCategory = (pathname: string): RuleEngineNavCategory | undefined => {

View File

@@ -24,6 +24,7 @@ function mapCompany(dto: Record<string, unknown>): Company {
const attrs = (dto.attributes as Record<string, unknown> | null) ?? {}; const attrs = (dto.attributes as Record<string, unknown> | null) ?? {};
return { return {
...(dto as unknown as Company), ...(dto as unknown as Company),
companyProfiles: (dto.companyProfiles as Company["companyProfiles"]) ?? [],
contactPersonName: (attrs.contactPersonName as string | null) ?? null, contactPersonName: (attrs.contactPersonName as string | null) ?? null,
contactPersonPhone: (attrs.contactPersonPhone as string | null) ?? null, contactPersonPhone: (attrs.contactPersonPhone as string | null) ?? null,
generalManagerName: (attrs.generalManagerName as string | null) ?? null, generalManagerName: (attrs.generalManagerName as string | null) ?? null,

View File

@@ -375,6 +375,7 @@ export interface TrainScheduleDetail {
weightTons: number; weightTons: number;
status: string | null; status: string | null;
schedulingStatus?: SchedulingStatus | null; schedulingStatus?: SchedulingStatus | null;
freightType?: FreightType | string | null;
}>; }>;
warnings?: string[]; warnings?: string[];
} }

View File

@@ -7,7 +7,7 @@ import {
export interface OperationsQueueGroups { export interface OperationsQueueGroups {
government: BookingListRow[]; government: BookingListRow[];
commercial: ThreeHourBookingBucket[]; commercial: ThreeHourBookingBucket<BookingListRow>[];
} }
export function groupBookingsForOperationsQueue( export function groupBookingsForOperationsQueue(

View File

@@ -1,40 +1,40 @@
import { URL_CONSTANTS } from "@/constants/URLS"; import { URL_CONSTANTS } from "@/constants/URLS";
import type {
AuthUser,
GenerateVerificationCodePayload,
LoginPayload,
LoginResponse,
OtpPayload,
OtpResponse,
SetPasswordPayload,
SignupPayload,
SignupResponse,
} from "@/types/auth";
import { client } from "@/utils/api"; import { client } from "@/utils/api";
import { ApiResponse } from "@edr/types"; import { ApiResponse } from "@edr/types";
import type {
AuthUser,
GenerateVerificationCodePayload,
LoginPayload,
LoginResponse,
OtpPayload,
OtpResponse,
SetPasswordPayload,
SignupPayload,
SignupResponse,
} from "@/types/auth";
export const authService = { export const authService = {
login: async (body: LoginPayload) => { login: async (body: LoginPayload) => {
const res = await client.post<ApiResponse<LoginResponse>>( const res = await client.post<LoginResponse>(
URL_CONSTANTS.AUTH.LOGIN, URL_CONSTANTS.AUTH.LOGIN,
body, body,
); );
return res.data.data; return res.data;
}, },
createUser: async (body: SignupPayload) => { createUser: async (body: SignupPayload) => {
const res = await client.post<ApiResponse<SignupResponse>>( const res = await client.post<SignupResponse & ApiResponse<void>> (
URL_CONSTANTS.USERS.SIGN_UP, URL_CONSTANTS.USERS.SIGN_UP,
body, body,
); );
return res.data.data; return res.data;
}, },
getMyInfo: async () => { getMyInfo: async () => {
const res = await client.get<ApiResponse<AuthUser>>( const res = await client.get<AuthUser>(
URL_CONSTANTS.USERS.ME, URL_CONSTANTS.USERS.ME,
); );
return res.data.data; return res.data;
}, },
generateVerificationCode: async (body: GenerateVerificationCodePayload) => { generateVerificationCode: async (body: GenerateVerificationCodePayload) => {