浏览代码

comenzando vista Condicionante

acampillo 11 月之前
父节点
当前提交
1f0ea49c91

+ 25 - 1
src/routers/routes.jsx

@@ -11,7 +11,8 @@ import {
   DatabaseOutlined,
   LockOutlined,
   UsergroupAddOutlined,
-  ApartmentOutlined
+  ApartmentOutlined,
+  UnorderedListOutlined 
 } from "@ant-design/icons";
 //Íconos de Ant Design
 
@@ -24,6 +25,7 @@ import { Usuarios, UsuarioDetalle } from "../views/admin/usuarios";
 
 /* CATÁLOGOS */
 import { Productos, ProductoDetalle } from "../views/catalogos/productos";
+import { Condicionantes, CondicionanteDetalle } from "../views/condicionantes";
 /* CATÁLOGOS */
 import { Perfil } from "../views/perfil";
 import { Modulos } from "../views/admin/permisos/modulos";
@@ -197,6 +199,28 @@ const dashboardRoutes = [
       },
     ],
   },
+  {
+    layout: "dashboard",
+    path: "/condicionantes",
+    name: "Condicionantes",
+    icon: <UnorderedListOutlined />,
+    sidebar: "single",
+    ver: "MENU-CODICIONANTES",
+    routes: [
+      {
+        path: "/",
+        element: Condicionantes,
+      },
+      {
+        path: "/agregar",
+        element: CondicionanteDetalle,
+      },
+      {
+        path: "/editar",
+        element: CondicionanteDetalle,
+      },
+    ],
+  },
   ...sharedRoutes,
 ];
 

+ 302 - 0
src/views/condicionantes/CondicionanteDetalle.jsx

@@ -0,0 +1,302 @@
+import { Form, Input, Button, Spin, Row, Col, Switch, Select as AntdSelect, Checkbox } from 'antd'
+import { useEffect, useMemo, useState } from 'react'
+import HttpService from '../../services/httpService'
+import { respuestas } from '../../utilities'
+import { useNavigate } from 'react-router-dom'
+import { useQuery, useModel } from '../../hooks'
+import { commonRules } from '../../constants/rules'
+import { Select } from '../../components'
+
+const selectores = {
+  productos: {
+    name: "producto",
+    expand: "subproductos",
+  },
+}
+
+const endpoints = {
+  condicionante: "condicionante",
+};
+
+const amplitudes = [
+  {
+    value: "Familia",
+    label: "Familia",
+  },
+  {
+    value: "Familia (Varios)",
+    label: "Familia (Varios)",
+  },
+]
+
+const fines = [
+  {
+    value: "Consumo Humano",
+    label: "Consumo Humano",
+  },
+  {
+    value: "Polinización",
+    label: "Polinización",
+  }
+]
+
+const tipos = [
+  {
+    value: "Introducción",
+    label: "Introducción",
+  },
+  {
+    value: "Expotación",
+    label: "Expotación",
+  },
+  {
+    value: "Tránsito",
+    label: "Tránsito",
+  },
+  {
+    value: "Movilización (Salida)",
+    label: "Movilización (Salida)",
+  },
+  {
+    value: "Importación",
+    label: "Importación",
+  }
+]
+
+const ProductoDetalle = () => {
+  const [form] = Form.useForm()
+  const navigate = useNavigate()
+  const [loading, setLoading] = useState(false)
+  const query = useQuery()
+  const id = query.get("id")
+  const [request, setRequest] = useState({})
+  const [activa, setActiva] = useState(false)
+  const [subproductos, setSubproductos] = useState([])
+
+  // const extraParams = useMemo(() => ({
+  //   idAgenda: id,
+  // }), [id])
+
+  const requestParams = useMemo(() => ({
+    name: endpoints.condicionante,
+    // expand: 'subproductos',
+    id,
+    // extraParams
+  }), [id])
+
+
+  const { model, modelLoading } = useModel(request)
+
+  useEffect(() => {
+    if (id) {
+      setRequest(requestParams)
+    }
+    return () => {
+      setRequest({})
+    }
+  }, [id, requestParams])
+
+  useEffect(() => {
+    if (model) {
+      form.setFieldsValue({ //seteo cuando son varios
+        ...model,
+        subproductos: model.subproductos.map((subproducto, index) => ({
+          ...subproducto,
+          key: index
+        }))
+      })
+      if (model?.activa) {
+        setActiva(true)
+      }
+    }
+  }, [form, model])
+
+  const onFinish = async (values) => {
+    try {
+      setLoading(true);
+
+      let body = {
+        ...values,
+      };
+
+      if (id) {
+        body.id = id
+      }
+
+      const res = await HttpService.post(`${endpoints.producto}/guardar`, body);
+      respuestas(res);
+      if (res?.status === 200) {
+        navigate('/condicionantes')
+      }
+    } catch (error) {
+      console.log(error);
+      setLoading(false);
+    } finally {
+      setLoading(false);
+    }
+  }
+
+  if (modelLoading) {
+    return <Spin
+      size="large"
+      style={{ display: "block", margin: "auto", marginTop: "50px" }}
+    />
+  }
+
+  return (
+    <Form
+      layout="vertical"
+      name="basic"
+      form={form}
+      onFinish={onFinish}
+      onFinishFailed={() => { }}
+    >
+      <Row gutter={16}>
+        <Col span={24}>
+          <h2>Información del Condicionante</h2>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Título"
+            name="titulo"
+            rules={[
+              commonRules.requerido,
+            ]}
+          >
+            <Input />
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Descripción"
+            name="descripcion"
+            rules={[
+              commonRules.requerido,
+            ]}
+          >
+            <Input.TextArea rows={3} />
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Activa"
+            name="activa"
+          >
+            <Switch
+              checkedChildren="Si"
+              unCheckedChildren="No"
+              style={{ backgroundColor: activa ? "#52c41a" : "#f5222d" }}
+              checked={activa}
+              onChange={(checked) => setActiva(checked)}
+            />
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Amplitud"
+            name="amplitud"
+            rules={[
+              commonRules.requerido,
+            ]}
+          >
+            <AntdSelect
+              showSearch
+              placeholder="Seleccione una amplitud"
+              optionFilterProp="children"
+              filterOption={(input, option) =>
+                option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
+              }
+            >
+              {amplitudes.map((amplitud) => (
+                <AntdSelect.Option key={amplitud.value} value={amplitud.value}>
+                  {amplitud.label}
+                </AntdSelect.Option>
+              ))}
+            </AntdSelect>
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Fines de Movilización"
+            name="fines"
+            rules={[
+              commonRules.requerido,
+            ]}
+          >
+            <Checkbox.Group>
+              {fines.map((fin) => (
+                <Checkbox key={fin.value} value={fin.value}>
+                  {fin.label}
+                </Checkbox>
+              ))}
+            </Checkbox.Group>
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Tipo de Movilización"
+            name="tipos"
+            rules={[
+              commonRules.requerido,
+            ]}
+          >
+            <Checkbox.Group>
+              {tipos.map((tipo) => (
+                <Checkbox key={tipo.value} value={tipo.value}>
+                  {tipo.label}
+                </Checkbox>
+              ))}
+            </Checkbox.Group>
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Especies"
+            name="idProducto"
+            rules={[commonRules.requerido]}
+          >
+            <Select
+              modelsParams={selectores.productos}
+              labelProp="nombre"
+              valueProp="idProducto"
+              append={[model?.producto]}
+              extraParams={{ padre: true }}
+              onChange={(_, item) => {
+                setSubproductos(item?.subproductos)
+                console.log(item)
+              }}
+            />
+          </Form.Item>
+        </Col>
+        <Col md={8} xs={24}>
+          <Form.Item
+            label="Subproductos"
+            name="subproductos"
+          >
+            <Checkbox.Group>
+              {subproductos.map((subproducto) => (
+                <Checkbox key={subproducto?.id} value={subproducto?.id}>
+                  {subproducto?.nombre}
+                </Checkbox>
+              ))}
+            </Checkbox.Group>
+          </Form.Item>
+        </Col>
+        <Col span={24}>
+          <Form.Item>
+            <Button
+              type="primary"
+              htmlType="submit"
+              style={{ marginTop: "30px" }}
+              loading={loading}
+            >
+              Guardar
+            </Button>
+          </Form.Item>
+        </Col>
+      </Row>
+    </Form>
+  )
+}
+
+export default ProductoDetalle

+ 174 - 0
src/views/condicionantes/Condicionantes.jsx

@@ -0,0 +1,174 @@
+import { useRef, useState } from "react";
+import { Form, Modal, Tooltip, notification } from "antd";
+import { DeleteOutlined, PlusOutlined } from "@ant-design/icons";
+import { Tabla } from "../../components";
+import { SimpleTableLayout } from "../../components/layouts";
+import { ActionsButton } from "../../components";
+import { isEllipsis } from "../../utilities";
+import { Link, useNavigate } from "react-router-dom";
+import Formulario from "./Formulario";
+import HttpService from "../../services/httpService";
+
+const endPoint = "condicionante";
+
+const Condicionantes = () => {
+  let tablaRef = useRef(null);
+  const navigate = useNavigate();
+  const [form] = Form.useForm();
+  const [buscarParams, setBuscarParams] = useState({});
+
+  const onFinish = (values) => {
+    const { q } = values;
+    const params = {
+      q: q ?? "",
+      padre: true,
+    };
+    setBuscarParams(params);    
+  };
+
+  const botones = [
+    {
+      onClick: () => navigate(`/condicionantes/agregar`),
+      props: { disabled: false, type: "primary", block: false },
+      text: "Nuevo",
+      icon: <PlusOutlined />,
+    },
+  ];
+
+  const linkText = (value, row, key) => (
+    <Link
+      to={`/condicionantes/editar?id=${row.id}`}
+      style={{ color: "black" }}
+    >
+      {isEllipsis(columns, key) ? (
+        <Tooltip title={value}>{value}</Tooltip>
+      ) : (
+        value
+      )}
+    </Link>
+  );
+
+  const eliminarRegistro = (nombre, id, url, alTerminar) => {
+    if (!id) return;
+    Modal.confirm({
+      title: "Eliminar",
+      content: `¿Está seguro de eliminar "${nombre}"?`,
+      icon: <DeleteOutlined style={{ color: "#ff0000" }} />,
+      okText: "Eliminar",
+      okButtonProps: {
+        type: "primary",
+        danger: true,
+      },
+      cancelText: "Cancelar",
+      onOk: async () => {
+        try {
+          let body = { id: id };
+          if (typeof id === "object") {
+            body = id;
+          }
+          const res = await HttpService.delete(url, body);
+          if (res && res.status === 200) {
+            notification.success({
+              message: "Éxito",
+              description: res?.mensaje,
+            });
+            alTerminar && alTerminar();
+          } else if (res?.status === 400) {
+            notification.error({
+              message: "Atención",
+              description: res?.mensaje,
+            });
+          }
+        } catch (error) {
+          console.log(error);
+          notification.error({
+            message: "Error",
+            description: error,
+          });
+          return "error";
+        }
+      },
+    });
+  };
+
+  const columns = [
+    {
+      title: "Acciones",
+      key: "id",
+      dataIndex: "id",
+      width: 100,
+      align: "center",
+      render: (_, item) => (
+        <ActionsButton
+          data={[
+            {
+              label: "Editar",
+              onClick: () =>
+                navigate(`/condicionantes/editar?id=${item?.id}`),
+            },
+            {
+              label: "Eliminar",
+              onClick: () => {
+                eliminarRegistro(item?.titulo, item?.id, endPoint+'/eliminar', () =>
+                  tablaRef?.current?.refresh()
+                );
+              },
+              danger: true,
+            },
+          ]}
+        />
+      ),
+    },
+    {
+      title: "Título",
+      key: "titulo",
+      dataIndex: "titulo",
+      render: linkText,
+    },
+    {
+      title: "Descripción",
+      key: "descripcion",
+      dataIndex: "descripcion",
+      render: linkText,
+    },
+    {
+      title: "Activa",
+      key: "activa",
+      dataIndex: "activa",
+      render: linkText,
+    },
+    {
+      title: "Editado por",
+      key: "editadoPor",
+      dataIndex: "editadoPor",
+      render: linkText,
+    },
+    {
+      title: "Fecha de Edición",
+      key: "fechaEdicion",
+      dataIndex: "fechaEdicion",
+      render: linkText,
+    }
+  ];
+
+  return (
+    <SimpleTableLayout
+      btnGroup={{
+        btnGroup: botones,
+      }}
+    >
+      <Formulario
+        form={form}
+        onFinish={onFinish} 
+      />
+      <Tabla
+        columns={columns}
+        nameURL={endPoint}
+        extraParams={buscarParams}
+        scroll={{ x: "30vw" }}
+      />
+    </SimpleTableLayout>
+  );
+};
+
+export default Condicionantes;

+ 55 - 0
src/views/condicionantes/Formulario.jsx

@@ -0,0 +1,55 @@
+import { Form, Input, Button, Row, Col } from 'antd'
+import PropTypes from 'prop-types'
+
+// const selectores = {
+//   consejoElectoral: {
+//     name: "v1/consejo-electoral",
+//   },
+// }
+
+const Formulario = ({
+  form,
+  onFinish,
+}) => {
+  return (
+    <Form
+      layout="vertical"
+      name="basic"
+      form={form}
+      initialValues={{ remember: true }}
+      onFinish={onFinish}
+      onFinishFailed={() => { }}
+    >
+      <Row gutter={16}>
+        <Col span={6}>
+
+
+          <Form.Item
+            label="Búsqueda"
+            name="q"
+          >
+            <Input />
+          </Form.Item>
+        </Col>
+        <Col span={6}>
+          <Form.Item>
+            <Button
+              type="primary"
+              htmlType="submit"
+              style={{ marginTop: "30px" }}
+            >
+              Buscar
+            </Button>
+          </Form.Item>
+        </Col>
+      </Row>  
+    </Form>
+  )
+}
+
+export default Formulario
+
+Formulario.propTypes = {
+  form: PropTypes.object.isRequired,
+  onFinish: PropTypes.func.isRequired,
+}

+ 7 - 0
src/views/condicionantes/index.js

@@ -0,0 +1,7 @@
+import Condicionantes from './Condicionantes'
+import CondicionanteDetalle from './CondicionanteDetalle'
+
+export {
+  Condicionantes,
+  CondicionanteDetalle
+}