Master Detail del monitor de operaciones quedo de lujo

develop
Al Garcia 2 years ago
parent ee10f1d43b
commit dc30111972
  1. 4
      src/App.tsx
  2. 196
      src/Components/Operaciones/OpMonitor.tsx
  3. 1
      src/Components/Operaciones/OpViajes.tsx
  4. 23
      src/Components/Operaciones/Viaje/Viaje.tsx
  5. 72
      src/Components/Operaciones/ViajesServicios/ViajesServicios.tsx
  6. 2
      src/DTOs/Operaciones/DTOViajes.ts
  7. 6
      src/DTOs/Operaciones/DTOViajesServicios.ts
  8. 10
      src/Services/Operaciones/OpViajes.Services.ts
  9. 44
      src/css/masterDetail.css
  10. 32
      src/store/features/Operaciones/OpViajesServiciosSlice.ts
  11. 4
      src/store/store.ts

@ -20,9 +20,9 @@ import { OpMonitor } from './Components/Operaciones/OpMonitor'
function App() {
const UserLogued = useSelector((state: RootState) => state.UserProfile.UserProfile.logueado)
useEffect(() => {
/* useEffect(() => {
console.log('Entro al proceso de router ' + UserLogued)
}, [UserLogued])
}, [UserLogued]) */
function PageNotFound() {
return (

@ -1,17 +1,19 @@
import React, { FC, useEffect, useState } from 'react'
import { Alert, Button, Card, Col, Form, Modal, Row, Table } from 'react-bootstrap'
import { IconContext } from 'react-icons'
import { BsFillPencilFill, BsPlusSquareFill } from 'react-icons/bs'
import { BsChevronDown, BsChevronUp, BsFillPencilFill, BsPlusSquareFill } from 'react-icons/bs'
import { useDispatch, useSelector } from 'react-redux'
import { RootState } from '../../store/store'
import DTOOpViajes from '../../DTOs/Operaciones/DTOViajes'
import DSOpViajes from '../../Services/Operaciones/OpViajes.Services'
import { ViajesServicios } from './ViajesServicios/ViajesServicios'
import { populateOpViajes } from '../../store/features/Operaciones/OpViajesSlice'
import { populateOpViajes, updateOpViajes } from '../../store/features/Operaciones/OpViajesSlice'
import { Viaje } from './Viaje/Viaje'
import '../../css/masterDetail.css'
import {
populateOpViajesServicios,
updateOpViajesServicios,
} from '../../store/features/Operaciones/OpViajesServiciosSlice'
interface IProps {}
@ -25,6 +27,7 @@ export const OpMonitor: FC<IProps> = (props) => {
const CatUbicaciones = useSelector((state: RootState) => state.CatUbicaciones.CatUbicaciones)
const CatServicios = useSelector((state: RootState) => state.CatServicios.CatServicios)
const AllTrips = useSelector((state: RootState) => state.OpViajes.OpViajes)
const AllTripsServices = useSelector((state: RootState) => state.OpViajesServicios.OpViajesServicios)
const [OpViajes, setOpViajes] = useState<DTOOpViajes[]>([])
const [showTripDialog, setShowTripDialog] = useState(false)
const [Switch, setSwitch] = useState(false)
@ -98,6 +101,7 @@ export const OpMonitor: FC<IProps> = (props) => {
hazmat: Hazmat,
noCaja: NoCaja,
pickUpNumber: PickUpNumber,
max: true,
}
DSOpViajes.Append(data)
.then((response) => {
@ -119,54 +123,54 @@ export const OpMonitor: FC<IProps> = (props) => {
})
setOpViajes(data)
dispatch(populateOpViajes(data))
DSOpViajes.GetAllServices()
.then((responsed) => {
dispatch(populateOpViajesServicios(responsed.data))
})
.catch((e: Error) => {})
})
.catch((e: Error) => {})
}
const changeToggle = (row: DTOOpViajes) => {
const data = OpViajes
for (const obj of data) {
if (obj.id === row.id) {
obj.max = !obj.max
setSwitch(obj.max)
break
let x = AllTrips.filter((a) => {
if (a.id === row.id) {
return a
}
})
if (x) {
const obj = { ...x[0] }
obj.max = !obj.max
dispatch(updateOpViajes(obj))
}
// console.log('La informacion ha cambiado: ' + JSON.stringify(data))
setOpViajes(data)
}
return (
<div>
<Card>
<Card.Title style={{ textAlign: 'left' }}>
<Alert variant='primary'>
<Row>
<Col xs={2} style={{ textAlign: 'right' }}>
AOL : Monitor de viajes
</Col>
<Col xs={1} style={{ textAlign: 'left', cursor: 'pointer' }}>
<div
onClick={() => {
newTrip()
}}
title='De un click aqui para crear un nuevo viaje'
>
<IconContext.Provider value={{ color: 'green', size: '28px' }}>
<BsPlusSquareFill />
</IconContext.Provider>
</div>
</Col>
<Col xs={9}></Col>
</Row>
</Alert>
</Card.Title>
<Card style={{ textAlign: 'left' }}>
<Alert variant='primary'>
<Row>
<Col xs={3} style={{ textAlign: 'right', fontSize: '25px' }}>
AOL : Monitor de viajes
</Col>
<Col xs={1} style={{ textAlign: 'left', cursor: 'pointer' }}>
<div
onClick={() => {
newTrip()
}}
title='De un click aqui para crear un nuevo viaje'
>
<IconContext.Provider value={{ color: 'green', size: '28px' }}>
<BsPlusSquareFill />
</IconContext.Provider>
</div>
</Col>
<Col xs={8}></Col>
</Row>
</Alert>
</Card>
<Row>
<Col xs={12}>&nbsp;</Col>
</Row>
<Row>
<Col xs={12}>
<Col xs={10}>
<Form.Control
type='text'
size='sm'
@ -176,6 +180,9 @@ export const OpMonitor: FC<IProps> = (props) => {
}}
/>
</Col>
<Col xs={2} className='totalLabel'>
Total: {AllTrips.length} viajes en curso
</Col>
</Row>
<Card>
<Card.Body>
@ -184,6 +191,7 @@ export const OpMonitor: FC<IProps> = (props) => {
<thead style={{ position: 'sticky', top: '0' }}>
<tr>
<th>id</th>
<th>&nbsp;</th>
<th>Cliente</th>
<th>Servicio</th>
<th>Proveedor</th>
@ -198,32 +206,102 @@ export const OpMonitor: FC<IProps> = (props) => {
</tr>
</thead>
<tbody>
{OpViajes
? OpViajes.map((MasterData) => {
{AllTrips
? AllTrips.map((MasterData) => {
return (
<>
<tr
key={MasterData.id}
onClick={() => {
changeToggle(MasterData)
}}
style={{ cursor: 'pointer' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
<td style={{ textAlign: 'left' }}>{MasterData.id}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sCliente}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sServicio}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sProveedor}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sOrigen}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sDestino}</td>
<td style={{ textAlign: 'left' }}>{MasterData.sTipoUnidad}</td>
<td style={{ textAlign: 'left' }}>{MasterData.noCaja}</td>
<td style={{ textAlign: 'left' }}>{MasterData.hazmat}</td>
<td style={{ textAlign: 'left' }}>{MasterData.refAgenciaAduanal}</td>
<td style={{ textAlign: 'left' }}>{MasterData.pickUpNumber}</td>
<td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.id}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
key={MasterData.id}
onClick={() => {
changeToggle(MasterData)
}}
>
{MasterData.max === true ? (
<IconContext.Provider value={{ color: 'blue', size: '15px' }}>
<BsChevronDown />
</IconContext.Provider>
) : (
<IconContext.Provider value={{ color: 'blue', size: '15px' }}>
<BsChevronUp />
</IconContext.Provider>
)}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sCliente}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sServicio}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sProveedor}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sOrigen}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sDestino}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.sTipoUnidad}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.noCaja}
</td>
<td
style={{ textAlign: 'center' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.hazmat === 1 ? 'Si' : 'No'}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.refAgenciaAduanal}
</td>
<td
style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
>
{MasterData.pickUpNumber}
</td>
<td className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}>
<Button
size='sm'
variant='light'
variant='white'
style={{ textAlign: 'right' }}
onClick={() => {
EditMaster(MasterData)
@ -235,7 +313,7 @@ export const OpMonitor: FC<IProps> = (props) => {
</Button>
</td>
</tr>
{MasterData.max === true && Switch === true ? (
{MasterData.max === true ? (
<tr>
<th colSpan={2} style={{ backgroundColor: '#F8F9FE' }}></th>
<th colSpan={14} style={{ backgroundColor: '#F8F9FE' }}>

@ -171,6 +171,7 @@ export const OpViajes: FC<IProps> = (props) => {
hazmat: Hazmat,
noCaja: NoCaja,
pickUpNumber: PickUpNumber,
max: true,
}
DSOpViajes.Append(data)
.then((response) => {

@ -5,6 +5,8 @@ import DTOOpViajes from '../../../DTOs/Operaciones/DTOViajes'
import DSOpViajes from '../../../Services/Operaciones/OpViajes.Services'
import { updateOpViajes } from '../../../store/features/Operaciones/OpViajesSlice'
import { RootState } from '../../../store/store'
import { populateOpViajesServicios } from '../../../store/features/Operaciones/OpViajesServiciosSlice'
import DTOViajesServicios from '../../../DTOs/Operaciones/DTOViajesServicios'
interface IProps {
IDViaje: number
@ -38,7 +40,6 @@ export const Viaje: FC<IProps> = (props) => {
useEffect(() => {
let selectedRow = mAllTrips.filter((row) => {
console.log(row.id)
if (row.id === props.IDViaje) {
setIDViaje(row.id)
setRefAA(row.refAgenciaAduanal)
@ -58,7 +59,20 @@ export const Viaje: FC<IProps> = (props) => {
// console.log(JSON.stringify(selectedRow) + ' ' + props.IDViaje)
}, [props.IDViaje])
const addNewService = () => {}
const addService = () => {
const data: DTOViajesServicios = {
id: 0,
idServicio: IDNuevoServicio,
sServicio: '',
idViaje: props.IDViaje,
}
DSOpViajes.AppendServices(data)
.then((responsed) => {
console.log('Item regresado del post=' + JSON.stringify(responsed.data))
dispatch(populateOpViajesServicios(responsed.data))
})
.catch((e: Error) => {})
}
const saveInfo = () => {
const data: DTOOpViajes = {
@ -82,9 +96,12 @@ export const Viaje: FC<IProps> = (props) => {
hazmat: Hazmat,
noCaja: NoCaja,
pickUpNumber: PickUpNumber,
max: true,
}
DSOpViajes.Append(data)
.then((response) => {
const data = response.data
data['max'] = false
dispatch(updateOpViajes(data))
})
.catch((e: Error) => {})
@ -326,7 +343,7 @@ export const Viaje: FC<IProps> = (props) => {
<Button
variant='warning'
onClick={() => {
addNewService()
addService()
}}
>
Agrega

@ -1,34 +1,76 @@
import React, { FC, useState } from 'react'
import { Button } from 'react-bootstrap'
import { IconContext } from 'react-icons'
import { BsFillPencilFill, BsXSquareFill } from 'react-icons/bs'
import { useDispatch, useSelector } from 'react-redux'
import DTOOpViajes from '../../../DTOs/Operaciones/DTOViajes'
import DTOViajesServicios from '../../../DTOs/Operaciones/DTOViajesServicios'
import { RootState } from '../../../store/store'
import DSOpViajes from '../../../Services/Operaciones/OpViajes.Services'
import { deleteOpViajesServicios } from '../../../store/features/Operaciones/OpViajesServiciosSlice'
interface IProps {
DataMaster: DTOOpViajes
}
/**
* @author
* @function @ViajesServicios
**/
export const ViajesServicios: FC<IProps> = (props) => {
const dispatch = useDispatch()
const AllTripsServices = useSelector((state: RootState) => state.OpViajesServicios.OpViajesServicios)
const [DisplayTable, setDisplayTable] = useState(true)
const deleteService = (id: number) => {
DSOpViajes.DeleteService(id)
.then((responsed) => {
dispatch(deleteOpViajesServicios(id))
})
.catch((e: Error) => {})
}
return (
<div>
<table className='zui-table zui-table-rounded'>
<thead>
<tr>
<th style={{ width: '50px', textAlign: 'center' }}>Partida</th>
<th style={{ width: '100px', textAlign: 'right' }}>Peso bruto</th>
<th style={{ width: '100px', textAlign: 'right' }}>Pallets</th>
<th style={{ width: '250px', textAlign: 'left' }}>Producto Materia Prima</th>
<th style={{ width: '180px' }}>Fraccion Arancelaria</th>
<th style={{ width: '100px' }}>Clave SAT</th>
<th style={{ width: '250px' }}>Concepto Producto MP</th>
<th style={{ width: '50px', textAlign: 'center' }}>Edita</th>
<th style={{ width: '300px' }}>Empaque (descripcion)</th>
<th style={{ width: '100px' }}>Clave SAT</th>
<th style={{ width: '50px', textAlign: 'center' }}>id</th>
<th style={{ width: '300px', textAlign: 'left' }}>Servicio</th>
<th style={{ width: '50px', textAlign: 'center' }}></th>
</tr>
</thead>
<tbody>
{AllTripsServices
? AllTripsServices.filter(function (service) {
return service.idViaje === props.DataMaster.id
}).map(function (service) {
return (
<tr
key={service.id}
onClick={() => {
// changeToggle(MasterData)
}}
style={{ cursor: 'pointer' }}
>
<td style={{ textAlign: 'left', paddingLeft: '5px' }}>{service.id}</td>
<td style={{ textAlign: 'left' }}>{service.sServicio}</td>
<td>
<Button
size='sm'
variant='white'
style={{ textAlign: 'right' }}
title='De un click aqui para eliminar el servicio'
onClick={() => {
deleteService(service.id)
}}
>
<IconContext.Provider value={{ color: 'red', size: '20px' }}>
<BsXSquareFill />
</IconContext.Provider>
</Button>
</td>
</tr>
)
})
: ''}
</tbody>
</table>
</div>
)

@ -19,5 +19,5 @@ export default interface DTOOpViajes {
sDestino: string,
servicio: number,
sServicio: string,
max?: boolean
max: boolean
}

@ -0,0 +1,6 @@
export default interface DTOViajesServicios {
id: number,
idViaje: number,
idServicio: number,
sServicio: string
}

@ -1,16 +1,26 @@
import http from "../../Services/Auth/config/http-common";
import DTOViajes from "../../DTOs/Operaciones/DTOViajes";
import IRespuesta from "../../Interfaces/Respuestas/IRespuesta";
import DTOViajesServicios from "../../DTOs/Operaciones/DTOViajesServicios";
class OpViajesDataService {
Get() {
return http.get<DTOViajes[]>("Operaciones/OpViajes/Get");
}
GetAllServices() {
return http.get<DTOViajesServicios[]>("Operaciones/OpViajes/GetAllServices");
}
Append(data: DTOViajes) {
return http.post<DTOViajes>(`Operaciones/OpViajes/Append`,data);
}
AppendServices(data: DTOViajesServicios) {
return http.post<DTOViajesServicios[]>(`Operaciones/OpViajes/AppendService`,data);
}
Delete(id: number) {
return http.delete<IRespuesta>(`Operaciones/OpViajes/Delete/${id}`);
}
DeleteService(id: number) {
return http.delete<IRespuesta>(`Operaciones/OpViajes/DeleteService/${id}`);
}
}
export default new OpViajesDataService();

@ -1,5 +1,5 @@
.MDTable {
width: 1500px;
width: 100%;
font-size: 0.6em;
font-family: Verdana, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
background-color: #ffffff;
@ -28,7 +28,7 @@
background-color: #255dde;
color: #FFFFFF;
height: 25px;
text-align: left;
text-align: left !important;
}
.MDTable tbody tr td {
@ -53,6 +53,38 @@
overflow: auto;
}
.totalLabel {
color: #f4a005;
font-size: larger;
font-weight: bold;
background-color: #ffffff;
text-shadow: 1px 1px 1px rgb(246, 218, 6);
font-family:'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif
}
.masterSelected {
/* background-color: #dbe5f3 !important; */
/* font-weight: bold; */
color: #000000;
/* border-top: solid 2px #f40505;*/
border-bottom: solid 2px #f4a005;
/* text-shadow: 1px 1px 1px #fff; */
/* background-color: #72a9a9 !important;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; */
}
.notmalSelected {
/* background-color: #6695db !important; */
/* font-weight: bold; */
color: #000000;
border-top: none;
border-bottom: none;
text-align: center;
/* text-shadow: 1px 1px 1px #fff; */
/* background-color: #72a9a9 !important;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; */
}
.zui-table {
border: solid 1px #DDEEEE;
border-collapse: collapse;
@ -70,7 +102,7 @@
}
.zui-table tbody td {
border: dotted 1px #DDEEEE;
border: solid 1px #DDEEEE;
color: #333;
padding: 0px;
text-shadow: 1px 1px 1px #fff;
@ -83,7 +115,7 @@
}
.zui-table-rounded thead th {
background-color: #CFAD70;
background-color: #70c1cf;
border: none;
text-shadow: 1px 1px 1px #ccc;
color: #333;
@ -99,8 +131,8 @@
.zui-table-rounded tbody tr td {
border: none;
border-top: dotted 1px #09840f;
background-color: #EED592;
border-top: solid 1px #09840f;
background-color: #ffffff;
border-bottom: none;
}

@ -0,0 +1,32 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import DTOViajesServicios from '../../../DTOs/Operaciones/DTOViajesServicios'
const OpViajesServicios: DTOViajesServicios[] = []
const initialState = { OpViajesServicios }
export const OpViajesServiciosSlice = createSlice({
name: 'OpViajesServicios',
initialState: initialState,
reducers: {
resetOpViajesServicios : (state, action: PayloadAction<string>) => {
state.OpViajesServicios = []
},
populateOpViajesServicios : (state, action: PayloadAction<DTOViajesServicios[]>) => {
action.payload.forEach(element => {
const index = state.OpViajesServicios.findIndex(object => object.id === element.id)
if (index<0) state.OpViajesServicios.push(element)
})
},
updateOpViajesServicios : (state, action: PayloadAction<DTOViajesServicios>) => {
const i = state.OpViajesServicios.findIndex(_element => _element.id === action.payload.id);
if (i > -1) state.OpViajesServicios[i] = action.payload;
else state.OpViajesServicios.push(action.payload);
},
deleteOpViajesServicios : (state, action: PayloadAction<number>) => {
const newArr = state.OpViajesServicios.filter(data => data.id != action.payload);
state.OpViajesServicios=newArr
},
},
})
export const { resetOpViajesServicios, populateOpViajesServicios, updateOpViajesServicios, deleteOpViajesServicios } = OpViajesServiciosSlice.actions;
export default OpViajesServiciosSlice.reducer;

@ -8,6 +8,7 @@ import { CatServiciosSlice } from './features/Catalogos/CatServiciosSlice'
import { CatTipoUnidadesSlice } from './features/Catalogos/CatTipoUnidadesSlice'
import { CatUbicacionesSlice } from './features/Catalogos/CatUbicacionesSlice'
import { OpViajesSlice } from './features/Operaciones/OpViajesSlice'
import { OpViajesServiciosSlice } from './features/Operaciones/OpViajesServiciosSlice'
export const store = configureStore({
reducer: {
@ -18,7 +19,8 @@ export const store = configureStore({
CatTipoUnidades: CatTipoUnidadesSlice.reducer,
CatUbicaciones: CatUbicacionesSlice.reducer,
CatServicios: CatServiciosSlice.reducer,
OpViajes: OpViajesSlice.reducer
OpViajes: OpViajesSlice.reducer,
OpViajesServicios: OpViajesServiciosSlice.reducer
}
})

Loading…
Cancel
Save