diff --git a/package.json b/package.json index 6a829a4..1eb13e0 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "bootstrap": "^5.2.0", "jwt-decode": "^3.1.2", "react": "^18.2.0", + "react-autocomplete-pure": "^1.0.7", "react-bootstrap": "^2.5.0", + "react-bootstrap-typeahead": "^6.0.0", "react-currency-format": "^1.1.0", "react-data-table-component": "^7.5.3", "react-datepicker": "^4.8.0", diff --git a/src/Components/Operaciones/Viaje/Servicios/Servicios.tsx b/src/Components/Operaciones/Viaje/Servicios/Servicios.tsx index e0c71d8..7b48be6 100644 --- a/src/Components/Operaciones/Viaje/Servicios/Servicios.tsx +++ b/src/Components/Operaciones/Viaje/Servicios/Servicios.tsx @@ -108,7 +108,7 @@ export const Servicios: FC = (props) => { {service.sServicio} {service.noCaja} {getAduana(service.aduana)} - {service.cita} + {service.cita?.includes('1900') ? '' : service.cita} {service.sProveedor} {service.comentarios} {props.actionButtons ? ( diff --git a/src/Components/Operaciones/Viaje/Viaje.tsx b/src/Components/Operaciones/Viaje/Viaje.tsx index 32d3bee..25ac8b3 100644 --- a/src/Components/Operaciones/Viaje/Viaje.tsx +++ b/src/Components/Operaciones/Viaje/Viaje.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useState } from 'react' +import React, { FC, useEffect, useState, ChangeEvent, useCallback } from 'react' import { Alert, Button, Card, Col, Form, Modal, Row } from 'react-bootstrap' import { useDispatch, useSelector } from 'react-redux' import DTOOpViajes from '../../../DTOs/Operaciones/DTOViajes' @@ -13,18 +13,41 @@ import DTOViajesServicios from '../../../DTOs/Operaciones/DTOViajesServicios' import { Servicios } from '../Viaje/Servicios/Servicios' import DatePicker from 'react-datepicker' import 'react-datepicker/dist/react-datepicker.css' +import { Typeahead } from 'react-bootstrap-typeahead' // ES2015 +import 'react-bootstrap-typeahead/css/Typeahead.css' +import 'react-bootstrap-typeahead/css/Typeahead.bs5.css' +import ICatClientes from '../../../Interfaces/Catalogos/ICatClientes' +import { AutocompletePure, AutocompletePureProps, ChangeReason, RenderItem } from 'react-autocomplete-pure' +import { Autocomplete } from '../../Utils/Autocomplete/Autocomplete' + +type Film = { id: number; cliente: string } + +const renderItem: RenderItem = (item, { isHighlighted }) => ( + {item.cliente} +) + +const getSuggestionValue = (item: Film) => item.cliente interface IProps { IDViaje: number } +interface Option { + firstName: string + lastName: string +} + export const Viaje: FC = (props) => { + const [isOpen, setIsOpen] = useState(false) + const [suggestions, setSuggestions] = useState([]) + const [value, setValue] = useState('') + const dispatch = useDispatch() const mAllTrips = useSelector((state: RootState) => state.OpViajes.OpViajes) const mAllTripServices = useSelector((state: RootState) => state.OpViajesServicios.OpViajesServicios) const Info = JSON.parse(localStorage.getItem('tokenInfo') || '[]') const UserID = Info.UserId - const CatClientes = useSelector((state: RootState) => state.CatClientes.CatClientes) + const mCatClientes = useSelector((state: RootState) => state.CatClientes.CatClientes) const CatProveedores = useSelector((state: RootState) => state.CatProveedores.CatProveedores) const CatTipoUnidades = useSelector((state: RootState) => state.CatTipoUnidades.CatTipoUnidades) const CatUbicaciones = useSelector((state: RootState) => state.CatUbicaciones.CatUbicaciones) @@ -38,6 +61,7 @@ export const Viaje: FC = (props) => { const [IDViaje, setIDViaje] = useState(0) const [IDDetail, setIDDetail] = useState(0) const [IDCliente, setIDCliente] = useState(0) + const [Cliente, setCliente] = useState('') const [IDProveedor, setIDProveedor] = useState(0) const [IDServicio, setIDServicio] = useState(0) const [IDNuevoServicio, setIDNuevoServicio] = useState(0) @@ -54,6 +78,45 @@ export const Viaje: FC = (props) => { const [DisableAduana, setDisableAduana] = useState(true) const [TotalServicios, setTotalServicios] = useState(0) const [Cita, setCita] = useState() + const [singleSelections, setSingleSelections] = useState([]) + const [multiSelections, setMultiSelections] = useState([]) + + const handleChange: AutocompletePureProps['onChange'] = useCallback(async (_event, { value, reason }) => { + setValue(value) + console.log('value=' + value) + if (reason === 'INPUT') { + let newFilms = mCatClientes.filter((a) => { + if (a.cliente.includes(value)) { + return a + } + }) + //const newFilms = await fetchFilms(value) + setSuggestions(newFilms) + setIsOpen(Boolean(newFilms.length)) + } else if (reason === 'ENTER') { + setIsOpen(false) + } + }, []) + + const handleSelect: AutocompletePureProps['onSelect'] = useCallback((_event, { item }) => { + const value = getSuggestionValue(item) + setValue(value) + console.log('value=' + value) + setIsOpen(false) + }, []) + + const handleClickOutside = (_event: Event) => { + setIsOpen(false) + } + + const [options, setOptions] = useState([ + { firstName: 'Art', lastName: 'Blakey' }, + { firstName: 'John', lastName: 'Coltrane' }, + { firstName: 'Miles', lastName: 'Davis' }, + { firstName: 'Herbie', lastName: 'Hancock' }, + { firstName: 'Charlie', lastName: 'Parker' }, + { firstName: 'Tony', lastName: 'Williams' }, + ]) useEffect(() => { if (IDServicio > 0 && TotalServicios === 0) saveDetail() @@ -246,7 +309,20 @@ export const Viaje: FC = (props) => { Cliente - + {/* + { + setCliente(e.target.value) + }} + /> + + */} + {/* { @@ -256,8 +332,8 @@ export const Viaje: FC = (props) => { className='form-select form-select-sm dialogLabel' > - {CatClientes - ? CatClientes.map((c) => { + {mCatClientes + ? mCatClientes.map((c) => { return ( + */} + + { + if (cliente.id === IDCliente) { + return cliente + } + })} + id='Cliente' + labelKey='cliente' + onChange={(selected) => { + if (selected.length > 0) { + const valStringify = JSON.stringify(selected) + const valParse = JSON.parse(valStringify) + //console.log(valParse[0].id) + setIDCliente(valParse[0].id) + } + }} + options={mCatClientes} + placeholder='Seleccione el cliente...' + /> + {/* +
+ +
+ */}
Tipo Unidad diff --git a/src/Components/Utils/Autocomplete/Autocomplete.tsx b/src/Components/Utils/Autocomplete/Autocomplete.tsx new file mode 100644 index 0000000..45f1442 --- /dev/null +++ b/src/Components/Utils/Autocomplete/Autocomplete.tsx @@ -0,0 +1,89 @@ +import React, { FC, useEffect, useState } from 'react' +import { IconContext } from 'react-icons' +import { BsXLg } from 'react-icons/bs' +import { useSelector } from 'react-redux' +import ICatClientes from '../../../Interfaces/Catalogos/ICatClientes' +import { RootState } from '../../../store/store' + +interface IProps { + input: string +} + +export const Autocomplete: FC = (props) => { + const mCatClientes = useSelector((state: RootState) => state.CatClientes.CatClientes) + const [Cliente, setCliente] = useState('') + const [IDCliente, setIDCliente] = useState(0) + const [toggleSelect, setToggleSelect] = useState(false) + + const loadInfo = (data: ICatClientes) => { + setIDCliente(data.id) + setCliente(data.cliente) + setToggleSelect(false) + } + + const handleKeyDown = (event: any) => { + if (event.key === 'Enter') { + console.log('Pasa este informacion al parent component') + setToggleSelect(false) + } + } + + useEffect(() => { + if (Cliente.length > 0) setToggleSelect(true) + }, [Cliente]) + + return ( + <> +
+
+
+ + { + setCliente(e.target.value) + }} + onKeyDown={(e) => handleKeyDown(e)} + onFocus={() => setToggleSelect(true)} + /* onBlur={() => setToggleSelect(false)} */ + /> + { + setCliente('') + setToggleSelect(false) + }} + > + + + + +
+
    + {mCatClientes + ? mCatClientes.map((item, index) => { + return item.id > 0 && item.cliente.toLocaleLowerCase().includes(Cliente.toLocaleLowerCase()) ? ( +
  • + loadInfo(item)}> + {item.cliente} + +
  • + ) : ( + '' + ) + }) + : ''} +
+
+
+
+
+ + ) +} diff --git a/src/Constants/TargetURL.ts b/src/Constants/TargetURL.ts index 493ffbb..45af750 100644 --- a/src/Constants/TargetURL.ts +++ b/src/Constants/TargetURL.ts @@ -1,5 +1,5 @@ export class TargetURL { get() { - return (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') ? "https://localhost:7000/api" : "http://reportes.gemcousa.com:5000/api" + return (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') ? "https://localhost:7000/api" : "https://www.alphaomega.com.mx/AOLBackend/api" } } \ No newline at end of file diff --git a/src/css/generalStyles.css b/src/css/generalStyles.css index a46d107..0baff24 100644 --- a/src/css/generalStyles.css +++ b/src/css/generalStyles.css @@ -11,4 +11,4 @@ .rowSplit { padding-top: '5px' -} \ No newline at end of file +} diff --git a/src/css/masterDetail.css b/src/css/masterDetail.css index a33718b..1d4a46f 100644 --- a/src/css/masterDetail.css +++ b/src/css/masterDetail.css @@ -151,3 +151,40 @@ .zui-table-rounded tbody tr:last-child td:last-child { border-radius: 0 0 10px 0; } + +.parent { + position: relative; + margin-top: 0px; + z-index: 1; +} + +.child { + position: absolute; + margin-top: 30px; + width: 350px; + height: 150px; + background: rgb(245, 248, 248); + border-radius: 5px 5px 5px 5px; + padding: 2px; + border-style: outset; + overflow-y: scroll; +} + +.cleanLi { + list-style-type: none; + padding-left: 10px; + font-family: Verdana, Geneva, Tahoma, sans-serif; + font-size: 12px; + cursor: pointer; +} + +.divAutocomplete { + z-index: 1000; + position: relative; + height: 100px; + overflow: auto; + /* display: block; + + position: relative; */ +display: inline-block; +} diff --git a/yarn.lock b/yarn.lock index 008c29f..bee2b4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1042,6 +1042,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.13.8", "@babel/runtime@^7.14.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" + integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.3.3": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -1570,7 +1577,7 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@popperjs/core@^2.11.5", "@popperjs/core@^2.9.2": +"@popperjs/core@^2.10.2", "@popperjs/core@^2.11.5", "@popperjs/core@^2.11.6", "@popperjs/core@^2.9.2": version "2.11.6" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== @@ -1592,7 +1599,7 @@ redux-thunk "^2.4.1" reselect "^4.1.5" -"@restart/hooks@^0.4.6", "@restart/hooks@^0.4.7": +"@restart/hooks@^0.4.0", "@restart/hooks@^0.4.6", "@restart/hooks@^0.4.7": version "0.4.7" resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.7.tgz#d79ca6472c01ce04389fc73d4a79af1b5e33cd39" integrity sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A== @@ -3153,7 +3160,7 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== -classnames@^2.2.6: +classnames@^2.2.0, classnames@^2.2.6: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== @@ -3289,6 +3296,11 @@ compression@^1.7.4: safe-buffer "5.1.2" vary "~1.1.2" +compute-scroll-into-view@^1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz#6a88f18acd9d42e9cf4baa6bec7e0522607ab7ab" + integrity sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -5101,7 +5113,7 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -invariant@^2.2.4: +invariant@^2.2.1, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -7323,7 +7335,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -7418,6 +7430,29 @@ react-app-polyfill@^3.0.0: regenerator-runtime "^0.13.9" whatwg-fetch "^3.6.2" +react-autocomplete-pure@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/react-autocomplete-pure/-/react-autocomplete-pure-1.0.7.tgz#90aa91cadc77e307afa7c0e26d65824aa61504cd" + integrity sha512-aBvulPJtG9zV/FzKdq1cNFk7Sf2P56XrQt4QaOKEwm3KF1XV/O1fYwv/CYc+Q3xp9t6q8jwYFAzS4wQ5qHarug== + +react-bootstrap-typeahead@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/react-bootstrap-typeahead/-/react-bootstrap-typeahead-6.0.0.tgz#3b5601d30a4db2adcd3cf815fc36a0a176053f7d" + integrity sha512-0eTYwG8sYoY/jGO5Qxx1QMQyiVJlrSgo6xO77xxF93PqVLERgZEdbNMk+y/UX7/HTPcWN4tcCUqAEwVe1DVxog== + dependencies: + "@babel/runtime" "^7.14.6" + "@popperjs/core" "^2.10.2" + "@restart/hooks" "^0.4.0" + classnames "^2.2.0" + fast-deep-equal "^3.1.1" + invariant "^2.2.1" + lodash.debounce "^4.0.8" + prop-types "^15.5.8" + react-overlays "^5.2.0" + react-popper "^2.2.5" + scroll-into-view-if-needed "^2.2.20" + warning "^4.0.1" + react-bootstrap@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.5.0.tgz#e25e649e37f080d38eeb92ad5b4ed562a1d7de62" @@ -7540,6 +7575,20 @@ react-onclickoutside@^6.12.0: resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz#8e6cf80c7d17a79f2c908399918158a7b02dda01" integrity sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA== +react-overlays@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.2.1.tgz#49dc007321adb6784e1f212403f0fb37a74ab86b" + integrity sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA== + dependencies: + "@babel/runtime" "^7.13.8" + "@popperjs/core" "^2.11.6" + "@restart/hooks" "^0.4.7" + "@types/warning" "^3.0.0" + dom-helpers "^5.2.0" + prop-types "^15.7.2" + uncontrollable "^7.2.1" + warning "^4.0.3" + react-popper@^2.2.5: version "2.3.0" resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" @@ -7994,6 +8043,13 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +scroll-into-view-if-needed@^2.2.20: + version "2.2.29" + resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz#551791a84b7e2287706511f8c68161e4990ab885" + integrity sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg== + dependencies: + compute-scroll-into-view "^1.0.17" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -8900,7 +8956,7 @@ walker@^1.0.7: dependencies: makeerror "1.0.12" -warning@^4.0.0, warning@^4.0.2, warning@^4.0.3: +warning@^4.0.0, warning@^4.0.1, warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==