Merge branch 'develop' of https://git.disroot.org/minicx/hackaton_2023 into develop
This commit is contained in:
commit
6ce72e23c0
|
@ -89,7 +89,7 @@
|
|||
},
|
||||
{
|
||||
"id": 3,
|
||||
"inventoryNumber": "4523122",
|
||||
"inventoryNumber": "4523123",
|
||||
"position": 3,
|
||||
"type": "HalfCarriage",
|
||||
"isSick": false,
|
||||
|
@ -283,7 +283,7 @@
|
|||
},
|
||||
{
|
||||
"station": {
|
||||
"id": 2,
|
||||
"id": 3,
|
||||
"name": "Томусинская"
|
||||
},
|
||||
"park": {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
"@remix-run/dev": "^2.4.1",
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/eslint": "^8.56.0",
|
||||
"@types/lodash": "^4.14.202",
|
||||
"@types/node": "^18.19.3",
|
||||
"@types/react": "^18.2.45",
|
||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||
|
@ -45,6 +46,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@nextui-org/react": "^2.2.9",
|
||||
"@reduxjs/toolkit": "^2.0.1",
|
||||
"@remix-run/node": "^2.4.1",
|
||||
"@remix-run/react": "^2.4.1",
|
||||
"@remix-run/serve": "^2.4.1",
|
||||
|
@ -55,6 +57,8 @@
|
|||
"node-fetch": "^3.3.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "^9.0.4",
|
||||
"redux": "^5.0.1",
|
||||
"remix-auth": "^3.6.0",
|
||||
"remix-auth-form": "^1.4.0"
|
||||
}
|
||||
|
|
|
@ -2,21 +2,17 @@ import type { IStation } from 'app/services/api/interfaces.server';
|
|||
import React from 'react';
|
||||
import { Select, SelectSection, SelectItem } from '@nextui-org/react';
|
||||
|
||||
export default function ControlFormHeader({
|
||||
Stations,
|
||||
}: {
|
||||
Stations: IStation[];
|
||||
}) {
|
||||
return (
|
||||
export default function ControlFormHeader({stations}: {stations: IStation[]}) {
|
||||
return(
|
||||
<div id="control-form-header" className="flex gap-4">
|
||||
<Select
|
||||
label="Station filter"
|
||||
placeholder="Select a station"
|
||||
selectionMode="multiple"
|
||||
className="w-[250px]"
|
||||
size="sm"
|
||||
>
|
||||
{Stations.map((station) => (
|
||||
size='sm'
|
||||
>
|
||||
{stations.map((station) => (
|
||||
<SelectItem key={station.title} value={station.title}>
|
||||
{station.title}
|
||||
</SelectItem>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function controlTable() {
|
||||
return <div id="control-table"></div>;
|
||||
}
|
|
@ -214,7 +214,7 @@ export default function ModalFilter({ db }: { db: Tdb }) {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-4">
|
||||
<Button onPress={onOpen}>Фильтр</Button>
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
|
@ -302,6 +302,6 @@ export default function ModalFilter({ db }: { db: Tdb }) {
|
|||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Modal,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
Button,
|
||||
useDisclosure,
|
||||
Listbox,
|
||||
ListboxItem,
|
||||
Select,
|
||||
SelectItem,
|
||||
ModalFooter,
|
||||
} from '@nextui-org/react';
|
||||
import { IStationData } from 'app/services/api/interfaces.server';
|
||||
import { useSearchParams, useNavigate } from '@remix-run/react';
|
||||
|
||||
export default function ModalOperations () {
|
||||
const {isOpen, onOpen, onOpenChange} = useDisclosure();
|
||||
return (
|
||||
<>
|
||||
<Button onPress={onOpen}>Операции</Button>
|
||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||
<ModalContent>
|
||||
{(onClose) => (
|
||||
<>
|
||||
<ModalHeader className="flex flex-col gap-1">Операции</ModalHeader>
|
||||
<ModalBody className="w-[80%]">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Nullam pulvinar risus non risus hendrerit venenatis.
|
||||
Pellentesque sit amet hendrerit risus, sed porttitor quam.
|
||||
</p>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
Nullam pulvinar risus non risus hendrerit venenatis.
|
||||
Pellentesque sit amet hendrerit risus, sed porttitor quam.
|
||||
</p>
|
||||
<p>
|
||||
Magna exercitation reprehenderit magna aute tempor cupidatat consequat elit
|
||||
dolor adipisicing. Mollit dolor eiusmod sunt ex incididunt cillum quis.
|
||||
Velit duis sit officia eiusmod Lorem aliqua enim laboris do dolor eiusmod.
|
||||
Et mollit incididunt nisi consectetur esse laborum eiusmod pariatur
|
||||
proident Lorem eiusmod et. Culpa deserunt nostrud ad veniam.
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button color="danger" variant="light" onPress={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button color="primary" onPress={onClose}>
|
||||
Action
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</>
|
||||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -56,32 +56,10 @@ export default function NavbarCom() {
|
|||
Powered by EVRAZ
|
||||
</p>
|
||||
</NavbarBrand>
|
||||
<NavbarItem className="mx-auto">
|
||||
<Link color="foreground" to="#">
|
||||
Features
|
||||
</Link>
|
||||
</NavbarItem>
|
||||
<NavbarItem isActive>
|
||||
<Link to="#" aria-current="page">
|
||||
Customers
|
||||
</Link>
|
||||
</NavbarItem>
|
||||
<NavbarItem>
|
||||
<Link color="foreground" to="#">
|
||||
Integrations
|
||||
</Link>
|
||||
</NavbarItem>
|
||||
</NavbarContent>
|
||||
|
||||
<NavbarContent justify="end">
|
||||
<NavbarItem className="hidden lg:flex">
|
||||
<Link to="#">Login</Link>
|
||||
</NavbarItem>
|
||||
<NavbarItem>
|
||||
<Button as={Link} color="primary" to="#" variant="flat">
|
||||
Sign Up
|
||||
</Button>
|
||||
</NavbarItem>
|
||||
|
||||
</NavbarContent>
|
||||
|
||||
<NavbarMenu>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import { IPark, IStationData } from 'app/services/api/interfaces.server';
|
||||
import React from 'react';
|
||||
import Wagon from './wagon';
|
||||
import Locomotive from './locomotive';
|
||||
|
||||
export default function Park({park, railRoads}: {park: IPark, railRoads: IStationData[]}) {
|
||||
|
||||
return(
|
||||
<div id="control-park" className='relative mb-12 py-1 pl-8 pr-2 border-secondary-200 border-[1px]'>
|
||||
<div className="absolute left-0 top-0 w-6 h-full bg-secondary-200 flex justify-center items-center" style={{writingMode: "vertical-lr"}}>{park.name}</div>
|
||||
<div className='rounded-none'>
|
||||
{railRoads.map(railroad => (
|
||||
<div className='min-h-[62px] my-[1px] p-2 flex gap-[2px] border-b-[2px] border-secondary-200 text-center'>
|
||||
<div className="w-12 flex justify-center items-center ">
|
||||
{railroad.way.id}
|
||||
</div>
|
||||
<div className="w-[76px] flex justify-center items-center ">
|
||||
{railroad.wagons.length}
|
||||
</div>
|
||||
<div className="w-12 flex justify-center items-center border-[1px] border-secondary-150">
|
||||
{railroad.locomotives.filter(locomotive => locomotive.direction === "LEFT").length ?
|
||||
<Locomotive locomotive={railroad.locomotives.filter(locomotive => locomotive.direction === "LEFT")[0]}/>:""}
|
||||
</div>
|
||||
<div className="flex grow px-4 py-1 gap-3 border-[1px] border-secondary-150" >
|
||||
{railroad.wagons.sort().map(wagon => <Wagon wagon={wagon} key={wagon.id}/>)}
|
||||
</div>
|
||||
<div className="w-12 flex justify-center items-center border-[1px] border-secondary-150">
|
||||
{railroad.locomotives.filter(locomotive => locomotive.direction === "RIGHT").length ?
|
||||
<Locomotive locomotive={railroad.locomotives.filter(locomotive => locomotive.direction === "RIGHT")[0]}/>:""}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import type { IStation, IStationData } from 'app/services/api/interfaces.server';
|
||||
import React from 'react';
|
||||
import lodash from 'lodash';
|
||||
import Park from './Park';
|
||||
|
||||
const { uniqBy } = lodash;
|
||||
|
||||
export default function Station({station, stationData}: {station: IStation, stationData: IStationData[]}) {
|
||||
const parks = uniqBy(stationData.map((way)=>way.park),function (park) {return park.id});
|
||||
return(
|
||||
<div id="control-station" className="flex flex-col">
|
||||
<h2 className='ml-4 my-2'>{station.title}</h2>
|
||||
{parks.map(park => {
|
||||
const railRoads = stationData.filter(railroad => railroad.park.id == park.id);
|
||||
return(<Park park={park} railRoads={railRoads} key={park.id}/>)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { ILocomotive } from 'app/services/api/interfaces.server';
|
||||
import React from 'react';
|
||||
|
||||
export default function Locomotive({locomotive}: {locomotive: ILocomotive}) {
|
||||
return(
|
||||
<div id="locomotive" className='relative'>
|
||||
<div className="absolute left-[-5px] -top-2 text-[8px]">{locomotive.inventoryNumber}</div>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_212_29288)">
|
||||
<path d="M15.4281 5.61828C15.3198 5.59023 15.1055 5.53674 15.1055 5.53674L15.1049 3.15164C15.1049 2.64399 14.6879 2.17764 13.9496 1.9886C13.2403 1.80702 12.6737 1.65059 11.6001 1.57974C11.7804 1.42308 11.895 1.19262 11.895 0.934911C11.895 0.463055 11.5124 0.0804443 11.0404 0.0804443C10.5686 0.0804443 10.186 0.463007 10.186 0.934911C10.186 1.17036 10.2812 1.38342 10.4352 1.538H9.56442C9.71838 1.38342 9.81366 1.17036 9.81366 0.934911C9.81366 0.463055 9.4312 0.0804443 8.9592 0.0804443C8.48725 0.0804443 8.10473 0.463007 8.10473 0.934911C8.10473 1.19257 8.21923 1.42308 8.39967 1.57974C7.32596 1.65059 6.75949 1.80702 6.05018 1.9886C5.31192 2.17764 4.89484 2.64399 4.89484 3.15164L4.89417 5.53674C4.89417 5.53674 4.67983 5.59023 4.57166 5.61828C4.31405 5.68509 4.13428 5.9175 4.13428 6.18357V13.4062C4.13428 13.7287 4.39569 13.9902 4.7182 13.9902H15.2813C15.6038 13.9902 15.8652 13.7287 15.8652 13.4062V6.18352C15.8654 5.9175 15.6856 5.68504 15.4281 5.61828ZM6.23856 3.33033C7.21774 3.08784 8.21271 2.93973 9.20216 2.88899V4.75265C8.21304 4.8019 7.21846 4.94573 6.23856 5.18114V3.33033ZM10.0194 8.54176H9.98046C9.29103 8.54176 8.73012 7.98084 8.73012 7.29127C8.73012 6.60179 9.29103 6.04083 9.98046 6.04083H10.0194C10.7089 6.04083 11.2698 6.60179 11.2698 7.29127C11.2698 7.98084 10.7089 8.54176 10.0194 8.54176ZM13.7612 5.18114C12.7814 4.94569 11.7868 4.8019 10.7976 4.75265V2.88899C11.7871 2.93973 12.782 3.08784 13.7612 3.33033V5.18114Z" fill="#B1ADC2"/>
|
||||
<path d="M11.2917 16.7526H10.0001H8.70846L8.36987 17.7045C8.9073 17.7502 9.44467 17.7737 9.98062 17.7737H10.0195C10.5554 17.7737 11.0929 17.7502 11.6303 17.7045L11.2917 16.7526Z" fill="#B1ADC2"/>
|
||||
<path d="M15.2873 16.6358V15.1617C15.2873 14.871 15.0517 14.6355 14.7611 14.6355H5.23856C4.948 14.6355 4.7124 14.8711 4.7124 15.1617V16.6358C4.7124 16.8755 4.87454 17.085 5.10652 17.1451C5.25453 17.1834 5.40302 17.2196 5.55151 17.2545L4.91257 18.7028C4.77317 19.0187 4.91619 19.3878 5.23214 19.5271C5.31425 19.5634 5.39993 19.5805 5.48428 19.5805C5.72444 19.5805 5.95343 19.4413 6.0566 19.2075L6.80675 17.5069C6.98719 17.5371 7.16782 17.5649 7.34855 17.59L7.88402 16.0848C7.95487 15.8854 8.14368 15.7522 8.35521 15.7522H11.6444C11.856 15.7522 12.0448 15.8854 12.1157 16.0848L12.6511 17.59C12.8318 17.5649 13.0125 17.5371 13.1929 17.5069L13.943 19.2075C14.0462 19.4413 14.2752 19.5805 14.5154 19.5805C14.5996 19.5805 14.6854 19.5634 14.7675 19.5271C15.0835 19.3877 15.2264 19.0187 15.0872 18.7028L14.4483 17.2544C14.5967 17.2196 14.7451 17.1834 14.8932 17.145C15.1251 17.085 15.2873 16.8755 15.2873 16.6358Z" fill="#B1ADC2"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_212_29288">
|
||||
<rect width="19.5" height="19.5" fill="white" transform="translate(0.25 0.0804443)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function Park() {
|
||||
return <div id="control-park"></div>;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import type { IStationData } from 'app/services/api/interfaces.server';
|
||||
import React from 'react';
|
||||
|
||||
export default function Station({
|
||||
StationData,
|
||||
}: {
|
||||
StationData: IStationData;
|
||||
}) {
|
||||
return <div id="control-station"></div>;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { IWagon } from 'app/services/api/interfaces.server';
|
||||
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { selectWagon } from 'app/wagonsSlice';
|
||||
export default function Wagon({ wagon }: { wagon: IWagon }) {
|
||||
const colors: Record<string, string[]> = {
|
||||
НТС: ['#BCF3FF', '#2988AE'],
|
||||
|
@ -26,16 +27,25 @@ export default function Wagon({ wagon }: { wagon: IWagon }) {
|
|||
bottomFillColor = '#EB5835';
|
||||
bottomStrokeColor = '#E32112';
|
||||
}
|
||||
const wagons = useSelector(selectWagon);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const selectWagonHandle = (e: any) => {
|
||||
const id = e.currentTarget.getAttribute("wagon-id");
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="wagon relative flex flex-col items-center">
|
||||
<div id="wagon" wagon-id={wagon.id} onClick={selectWagonHandle} className=" w-fit relative flex flex-col items-center">
|
||||
<div className="relative top-[2px]">
|
||||
{WagonTop(wagon.type, topFillColor, topBorderColor)}
|
||||
</div>
|
||||
<div
|
||||
id="wagon_number"
|
||||
className={`absolute bottom-4 -left-2 w-4 h-4 bg-[${topFillColor}] border-[${topBorderColor}] border-[1px] text-[12px] text-center`}
|
||||
style={{backgroundColor: topFillColor, borderColor: topBorderColor, borderWidth: "1px"}}
|
||||
className="absolute flex justify-center items-center bottom-4 -left-2 w-4 h-4 text-[12px] text-center"
|
||||
>
|
||||
1
|
||||
{wagon.position}
|
||||
</div>
|
||||
<svg
|
||||
width="56"
|
|
@ -32,7 +32,7 @@ export default function App() {
|
|||
<body className="h-screen">
|
||||
<NextUIProvider>
|
||||
<NavbarCom />
|
||||
<main className="h-content bg-background text-foreground flex justify-center items-center">
|
||||
<main className="h-content bg-background text-foreground flex justify-center items-center p-4">
|
||||
<Outlet />
|
||||
</main>
|
||||
<ScrollRestoration />
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { createContext, useContext } from 'react';
|
||||
import { json, type LoaderFunctionArgs } from '@remix-run/node';
|
||||
import { authenticator } from '../services/auth.server';
|
||||
import { IStation, IStationData } from 'app/services/api/interfaces.server';
|
||||
import { api } from 'app/services/api/json.api.server';
|
||||
import { useLoaderData } from '@remix-run/react';
|
||||
import ControlFormHeader from 'app/coms/controlFormHeader';
|
||||
import ModalFilter from 'app/coms/modalFilter';
|
||||
import Station from 'app/coms/ui/Station';
|
||||
import { Provider } from 'react-redux'
|
||||
import { store } from 'app/wagonsSlice';
|
||||
import ModalOperations from 'app/coms/modalOperations';
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
const authData = await authenticator.isAuthenticated(request, {
|
||||
|
@ -28,15 +32,47 @@ export default function Index() {
|
|||
const { authData, stations, owners, stationsData, wagonTypeList } =
|
||||
useLoaderData<typeof loader>();
|
||||
return (
|
||||
<div id="control-form" className="w-full h-full p-2 flex flex-col">
|
||||
<ControlFormHeader Stations={stations} />
|
||||
<ModalFilter
|
||||
db={{
|
||||
stationsData: stationsData,
|
||||
ownersList: owners,
|
||||
wagonTypeList,
|
||||
}}
|
||||
></ModalFilter>
|
||||
<div id="index" className='w-full h-full'>
|
||||
<div className="flex justify-between">
|
||||
<ModalFilter
|
||||
db={{
|
||||
stationsData: stationsData,
|
||||
ownersList: owners,
|
||||
wagonTypeList,
|
||||
}}
|
||||
/>
|
||||
<ModalOperations />
|
||||
</div>
|
||||
<div id="control-form" className='w-full h-full flex flex-col rounded-sm border-secondary-200 border-[1px]'>
|
||||
<div className="h-9 mb-4 pl-4 bg-secondary-100 text-y-center rounded-t-sm flex items-center">
|
||||
АРМ дежурного станции
|
||||
</div>
|
||||
<div className='py-1 pl-10 pr-4 min-h-[62px] my-[1px] flex gap-[2px] text-center'>
|
||||
<div className="w-12 flex justify-center items-center ">
|
||||
Путь
|
||||
</div>
|
||||
<div className="w-[76px] flex justify-center items-center ">
|
||||
Всего
|
||||
</div>
|
||||
<div className="w-12 flex justify-center items-center">
|
||||
Л
|
||||
</div>
|
||||
<div className="flex grow justify-between items-center px-4 py-1 gap-3" >
|
||||
<span>(Чётная)</span>
|
||||
<span>Вагоны</span>
|
||||
<span>(Нечётная)</span>
|
||||
</div>
|
||||
<div className="w-12 flex justify-center items-center ">
|
||||
Л
|
||||
</div>
|
||||
</div>
|
||||
<Provider store={store}>
|
||||
{stations.map(station => {
|
||||
const stationData = stationsData.filter(el => el.station.id == station.id);
|
||||
return(<Station stationData={stationData} station={station} key={station.id}/>)
|
||||
})}
|
||||
</Provider>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -15,13 +15,11 @@ const endpoints = {
|
|||
getOwnersList: 'ownersList',
|
||||
getNorms: 'operationsTypesNorms',
|
||||
getOperationsTypes: 'operationsTypes',
|
||||
getUsers: 'users',
|
||||
getUsers:'users'
|
||||
};
|
||||
|
||||
export const api = new (class ApiDB {
|
||||
private readonly url = `http://localhost:${(
|
||||
env.DB_PORT ?? 4000
|
||||
).toString()}/`;
|
||||
private readonly url = `http://localhost:${(env.DB_PORT ?? 4000).toString()}/`;
|
||||
constructor() {}
|
||||
async getStations(): Promise<IStation[]> {
|
||||
const response = await fetch(this.url + endpoints.getStations, {
|
||||
|
@ -69,24 +67,23 @@ export const api = new (class ApiDB {
|
|||
});
|
||||
return (await response.json()) as IStationData[];
|
||||
}
|
||||
async getUsers() {
|
||||
const response = await fetch(this.url + endpoints.getUsers, {
|
||||
method: 'GET',
|
||||
});
|
||||
async getStationsData(): Promise<IStationData[]> {
|
||||
const response = await fetch(
|
||||
this.url + endpoints.getStationsData,
|
||||
{
|
||||
method: 'GET',
|
||||
},
|
||||
);
|
||||
return (await response.json()) as IStationData[];
|
||||
}
|
||||
async getUsers(){
|
||||
const response = await fetch(this.url + endpoints.getUsers,{method:"GET"});
|
||||
return (await response.json()) as IUser[];
|
||||
}
|
||||
async createUser(user: Omit<IUser, 'id'>) {
|
||||
const response = await fetch(this.url + endpoints.getUsers, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(user),
|
||||
});
|
||||
if (response.ok) {
|
||||
return (await response.json()) as IUser;
|
||||
} else {
|
||||
throw new Error('Unknown answer from db');
|
||||
}
|
||||
async createUser(user:Omit<IUser,"id">){
|
||||
const response = await fetch(this.url + endpoints.getUsers,{method:"POST",headers:{
|
||||
"Content-Type": "application/json",
|
||||
},body:JSON.stringify(user)});
|
||||
return response.ok
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { createSlice, configureStore } from '@reduxjs/toolkit'
|
||||
|
||||
const wagonSlice = createSlice({
|
||||
name: 'wagonsSlice',
|
||||
initialState: {
|
||||
selectedWagons: []
|
||||
},
|
||||
reducers: {
|
||||
selectWagon: (state, action) => {
|
||||
state.selectedWagons.find(action.payload) ?
|
||||
state.selectedWagons = state.selectedWagons.filter(el => el == action.payload):
|
||||
state.selectedWagons = <never[]>[...state.selectedWagons, action.payload]
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
export const { selectWagon } = wagonSlice.actions
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: wagonSlice.reducer
|
||||
})
|
Loading…
Reference in New Issue