mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 07:22:53 +00:00
resolve conflict
This commit is contained in:
@@ -82,17 +82,6 @@ export class TrainSchedulingService {
|
||||
async getEligibleContainerBookings(query: GetEligibleContainerBookingsDto) {
|
||||
const bookingRepository = this.dataSource.getRepository(Booking);
|
||||
const queryBuilder = bookingRepository
|
||||
<<<<<<< HEAD
|
||||
.createQueryBuilder('booking')
|
||||
.leftJoinAndSelect('booking.company', 'company')
|
||||
.leftJoinAndSelect('booking.originYard', 'originYard')
|
||||
.leftJoinAndSelect('booking.destinationYard', 'destinationYard')
|
||||
.leftJoinAndSelect('booking.bookingContainers', 'bookingContainer')
|
||||
.leftJoinAndSelect('bookingContainer.containerType', 'containerType')
|
||||
.leftJoin(TrainScheduleBooking, 'scheduleBooking', 'scheduleBooking.booking_id = booking.id')
|
||||
.where('booking.freightType = :freightType', { freightType: 'CONTAINER' })
|
||||
.andWhere('scheduleBooking.id IS NULL');
|
||||
=======
|
||||
.createQueryBuilder("booking")
|
||||
.leftJoinAndSelect("booking.customer", "customer")
|
||||
.leftJoinAndSelect("booking.originYard", "originYard")
|
||||
@@ -106,7 +95,6 @@ export class TrainSchedulingService {
|
||||
)
|
||||
.where("booking.freightType = :freightType", { freightType: "CONTAINER" })
|
||||
.andWhere("scheduleBooking.id IS NULL");
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
|
||||
if (query.originStationId) {
|
||||
queryBuilder.andWhere("booking.originYardId = :originStationId", {
|
||||
@@ -144,13 +132,6 @@ export class TrainSchedulingService {
|
||||
const items: EligibleBookingItem[] = bookings.map((booking) => ({
|
||||
id: booking.id,
|
||||
reference: booking.reference,
|
||||
<<<<<<< HEAD
|
||||
customer: booking.company?.name ?? booking.company?.email ?? 'Unknown customer',
|
||||
containerType: booking.bookingContainers
|
||||
?.map((container) => container.containerType?.label ?? container.containerType?.code ?? 'Container')
|
||||
.join(', ') ?? 'Container',
|
||||
quantity: booking.bookingContainers?.reduce((sum, container) => sum + Number(container.quantity ?? 0), 0) ?? 0,
|
||||
=======
|
||||
customer:
|
||||
booking.company?.name ?? booking.company?.email ?? "Unknown customer",
|
||||
containerType:
|
||||
@@ -167,7 +148,6 @@ export class TrainSchedulingService {
|
||||
(sum, container) => sum + Number(container.quantity ?? 0),
|
||||
0,
|
||||
) ?? 0,
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
weightTons: this.roundTons(booking.cargoTotalWeightVgm),
|
||||
origin:
|
||||
booking.originYard?.label ??
|
||||
@@ -674,17 +654,6 @@ export class TrainSchedulingService {
|
||||
}
|
||||
|
||||
async getContainerTrainScheduleById(id: string) {
|
||||
<<<<<<< HEAD
|
||||
const schedule = await this.dataSource.getRepository(TrainSchedule).findOne({
|
||||
where: { id },
|
||||
relations: {
|
||||
trainSet: { locomotive: true, wagons: { wagonType: true, allocations: { booking: true } } },
|
||||
originStation: true,
|
||||
destinationStation: true,
|
||||
scheduleBookings: { booking: { company: true, originYard: true, destinationYard: true } },
|
||||
},
|
||||
});
|
||||
=======
|
||||
const schedule = await this.dataSource
|
||||
.getRepository(TrainSchedule)
|
||||
.findOne({
|
||||
@@ -701,7 +670,6 @@ export class TrainSchedulingService {
|
||||
},
|
||||
},
|
||||
});
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
|
||||
if (!schedule) {
|
||||
throw new NotFoundException(`Train schedule ${id} not found`);
|
||||
|
||||
@@ -2,16 +2,6 @@ import { Injectable, Logger } from "@nestjs/common";
|
||||
import { randomUUID } from "crypto";
|
||||
import { DataSource } from "typeorm";
|
||||
|
||||
<<<<<<< HEAD
|
||||
import { BookingContainer } from '../modules/bookings/entities/booking-container.entity';
|
||||
import { Booking } from '../modules/bookings/entities/booking.entity';
|
||||
import { Company } from '../modules/companies/entities/company.entity';
|
||||
import { Locomotive } from '../modules/locomotives/entities/locomotive.entity';
|
||||
import { ServiceType } from '../modules/rule-engine/entities/service-type.entity';
|
||||
import { Yard } from '../modules/rule-engine/entities/yard.entity';
|
||||
import { WagonType } from '../modules/wagon-types/entities/wagon-type.entity';
|
||||
import { ContainerType } from '../modules/rule-engine/entities/container-type.entity';
|
||||
=======
|
||||
import { BookingContainer } from "../modules/bookings/entities/booking-container.entity";
|
||||
import { Booking } from "../modules/bookings/entities/booking.entity";
|
||||
import { Customer } from "../modules/customers/entities/customer.entity";
|
||||
@@ -20,7 +10,6 @@ import { ServiceType } from "../modules/rule-engine/entities/service-type.entity
|
||||
import { Yard } from "../modules/rule-engine/entities/yard.entity";
|
||||
import { WagonType } from "../modules/wagon-types/entities/wagon-type.entity";
|
||||
import { ContainerType } from "../modules/rule-engine/entities/container-type.entity";
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
|
||||
const SEED_FLAG = "SEED_DEMO_BOOKINGS";
|
||||
|
||||
@@ -220,11 +209,6 @@ export class DemoBookingsSeeder {
|
||||
{ conflictPaths: { email: true } },
|
||||
);
|
||||
|
||||
<<<<<<< HEAD
|
||||
const [serviceType, company, yards, containerTypes] = await Promise.all([
|
||||
manager.getRepository(ServiceType).findOneByOrFail({ code: SERVICE_TYPE_CODE }),
|
||||
manager.getRepository(Customer).findOneByOrFail({ email: CUSTOMER_EMAIL }),
|
||||
=======
|
||||
const [serviceType, customer, yards, containerTypes] = await Promise.all([
|
||||
manager
|
||||
.getRepository(ServiceType)
|
||||
@@ -232,7 +216,6 @@ export class DemoBookingsSeeder {
|
||||
manager
|
||||
.getRepository(Customer)
|
||||
.findOneByOrFail({ email: CUSTOMER_EMAIL }),
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
manager.getRepository(Yard).find(),
|
||||
manager.getRepository(ContainerType).find(),
|
||||
]);
|
||||
@@ -264,13 +247,8 @@ export class DemoBookingsSeeder {
|
||||
await manager.getRepository(Booking).upsert(
|
||||
{
|
||||
reference: demoBooking.reference,
|
||||
<<<<<<< HEAD
|
||||
companyId: company.id,
|
||||
status: 'APPROVED',
|
||||
=======
|
||||
companyId: customer.id,
|
||||
status: "APPROVED",
|
||||
>>>>>>> bd6ad54eea229305a214d06081e0ffd27fe163b8
|
||||
scheduledDate: new Date(demoBooking.scheduledDate),
|
||||
totalAmount: 0,
|
||||
paymentStatus: "PENDING",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"@edr/ui-common": "workspace:*",
|
||||
"@tanstack/react-query": "^5.100.11",
|
||||
"@tria-plc/iamui-common": "1.1.1",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"axios": "^1.7.7",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { Card, CardHeader, CardTitle, CardDescription, CardFooter, CardAction, CardContent } from '@edr/ui-common';
|
||||
@@ -1,42 +1,3 @@
|
||||
<<<<<<< HEAD
|
||||
import { useState } from 'react';
|
||||
import { useTrains, useDeleteTrain, useCreateTrain } from '@/hooks/useTrains';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { Plus, Eye, Trash2 } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const CreateTrainForm = ({ onSuccess }: { onSuccess: () => void }) => {
|
||||
const [form, setForm] = useState({ code: '', capacityTons: 0, trainNumber: '', trainName: '' });
|
||||
const createTrain = useCreateTrain();
|
||||
const { toast } = useToast();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
try {
|
||||
await createTrain.mutateAsync(form);
|
||||
toast({ title: 'Train created', description: `${form.code} added.` });
|
||||
onSuccess();
|
||||
} catch {
|
||||
toast({ title: 'Error', description: 'Failed to create train.', variant: 'destructive' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div><Label>Code*</Label><Input required value={form.code} onChange={e => setForm({...form, code: e.target.value})} /></div>
|
||||
<div><Label>Capacity (tons)*</Label><Input type="number" required value={form.capacityTons} onChange={e => setForm({...form, capacityTons: parseFloat(e.target.value)})} /></div>
|
||||
<div><Label>Train Number</Label><Input value={form.trainNumber} onChange={e => setForm({...form, trainNumber: e.target.value})} /></div>
|
||||
<div><Label>Train Name</Label><Input value={form.trainName} onChange={e => setForm({...form, trainName: e.target.value})} /></div>
|
||||
<Button type="submit" disabled={createTrain.isPending}>Save</Button>
|
||||
</form>
|
||||
=======
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { isAxiosError } from 'axios';
|
||||
@@ -794,45 +755,7 @@ const TrainsPage = () => {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
>>>>>>> 523d7e58422f1bde8024c2dd237092a7cf6aa190
|
||||
);
|
||||
};
|
||||
|
||||
export default function TrainsPage() {
|
||||
const { data: trains, isLoading } = useTrains();
|
||||
const deleteTrain = useDeleteTrain();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
if (isLoading) return <div className="p-8">Loading trains...</div>;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between">
|
||||
<CardTitle>Trains</CardTitle>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger asChild><Button size="sm"><Plus className="mr-2 h-4 w-4" />New Train</Button></DialogTrigger>
|
||||
<DialogContent><DialogHeader><DialogTitle>Create Train</DialogTitle></DialogHeader><CreateTrainForm onSuccess={() => setOpen(false)} /></DialogContent>
|
||||
</Dialog>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader><TableRow><TableHead>Number</TableHead><TableHead>Name</TableHead><TableHead>Status</TableHead><TableHead>Capacity</TableHead><TableHead>Actions</TableHead></TableRow></TableHeader>
|
||||
<TableBody>
|
||||
{trains?.map(train => (
|
||||
<TableRow key={train.id}>
|
||||
<TableCell>{train.trainNumber || train.code}</TableCell>
|
||||
<TableCell>{train.trainName || '-'}</TableCell>
|
||||
<TableCell><Badge variant="outline">{train.status}</Badge></TableCell>
|
||||
<TableCell>{train.capacityTons} t</TableCell>
|
||||
<TableCell className="flex space-x-2">
|
||||
<Link to={`/trains/${train.id}`}><Button variant="ghost" size="icon"><Eye className="h-4 w-4" /></Button></Link>
|
||||
<Button variant="ghost" size="icon" onClick={() => deleteTrain.mutate(train.id)}><Trash2 className="h-4 w-4" /></Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
export default TrainsPage;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { apiClient } from '@/lib/axios';
|
||||
|
||||
//import { apiClient } from '@/lib/axios';
|
||||
import { api as client } from "@/auth/http";
|
||||
export interface Train {
|
||||
id: string;
|
||||
code: string;
|
||||
@@ -17,10 +17,10 @@ export interface Train {
|
||||
}
|
||||
|
||||
export const trainService = {
|
||||
getAll: () => apiClient.get<Train[]>('/trains'),
|
||||
getById: (id: string) => apiClient.get<Train>(`/trains/${id}`),
|
||||
create: (data: Partial<Train>) => apiClient.post('/trains', data),
|
||||
update: (id: string, data: Partial<Train>) => apiClient.patch(`/trains/${id}`, data),
|
||||
delete: (id: string) => apiClient.delete(`/trains/${id}`),
|
||||
getDetails: (id: string) => apiClient.get(`/trains/${id}/details`),
|
||||
getAll: () => client.get<Train[]>('/trains'),
|
||||
getById: (id: string) => client.get<Train>(`/trains/${id}`),
|
||||
create: (data: Partial<Train>) => client.post('/trains', data),
|
||||
update: (id: string, data: Partial<Train>) => client.patch(`/trains/${id}`, data),
|
||||
delete: (id: string) => client.delete(`/trains/${id}`),
|
||||
getDetails: (id: string) => client.get(`/trains/${id}/details`),
|
||||
};
|
||||
33
pnpm-lock.yaml
generated
33
pnpm-lock.yaml
generated
@@ -184,6 +184,9 @@ importers:
|
||||
'@edr/ui-common':
|
||||
specifier: workspace:*
|
||||
version: link:../../../packages/ui-common
|
||||
'@hello-pangea/dnd':
|
||||
specifier: ^18.0.1
|
||||
version: 18.0.1(@types/react@18.3.29)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.100.11
|
||||
version: 5.100.11(react@19.2.6)
|
||||
@@ -1377,6 +1380,12 @@ packages:
|
||||
'@gilbarbara/deep-equal@0.3.1':
|
||||
resolution: {integrity: sha512-I7xWjLs2YSVMc5gGx1Z3ZG1lgFpITPndpi8Ku55GeEIKpACCPQNS/OTqQbxgTCfq0Ncvcc+CrFov96itVh6Qvw==}
|
||||
|
||||
'@hello-pangea/dnd@18.0.1':
|
||||
resolution: {integrity: sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ==}
|
||||
peerDependencies:
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6
|
||||
|
||||
'@hono/node-server@1.19.14':
|
||||
resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==}
|
||||
engines: {node: '>=18.14.1'}
|
||||
@@ -5331,6 +5340,9 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
css-box-model@1.2.1:
|
||||
resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==}
|
||||
|
||||
css-line-break@2.1.0:
|
||||
resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
|
||||
|
||||
@@ -8537,6 +8549,9 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
raf-schd@4.0.3:
|
||||
resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==}
|
||||
|
||||
raf@3.4.1:
|
||||
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
|
||||
|
||||
@@ -11264,6 +11279,18 @@ snapshots:
|
||||
|
||||
'@gilbarbara/deep-equal@0.3.1': {}
|
||||
|
||||
'@hello-pangea/dnd@18.0.1(@types/react@18.3.29)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.2
|
||||
css-box-model: 1.2.1
|
||||
raf-schd: 4.0.3
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
react-redux: 9.3.0(@types/react@18.3.29)(react@19.2.6)(redux@5.0.1)
|
||||
redux: 5.0.1
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
'@hono/node-server@1.19.14(hono@4.12.22)':
|
||||
dependencies:
|
||||
hono: 4.12.22
|
||||
@@ -16070,6 +16097,10 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
css-box-model@1.2.1:
|
||||
dependencies:
|
||||
tiny-invariant: 1.3.3
|
||||
|
||||
css-line-break@2.1.0:
|
||||
dependencies:
|
||||
utrie: 1.0.2
|
||||
@@ -19735,6 +19766,8 @@ snapshots:
|
||||
'@types/react': 18.3.29
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.29)
|
||||
|
||||
raf-schd@4.0.3: {}
|
||||
|
||||
raf@3.4.1:
|
||||
dependencies:
|
||||
performance-now: 2.1.0
|
||||
|
||||
Reference in New Issue
Block a user