asignar-descarga.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <style>
  2. .site-card {
  3. min-height: 100vh;
  4. width: 100vw;
  5. padding: 20px;
  6. background: #ececec;
  7. }
  8. .content {
  9. width: 100%;
  10. height: 100%;
  11. }
  12. .full-width {
  13. width: 100%;
  14. }
  15. </style>
  16. <script type="text/babel">
  17. const url = "https://api.fourier.audio";
  18. const urlDescarga = "https://descarga.fourier.audio";
  19. const { LoadingOutlined } = window.icons;
  20. const { Card, Select, Spin, Row, Col, Form, Input, Button, Modal, DatePicker, Table, Popconfirm, Checkbox } = window.antd;
  21. const { Option } = Select;
  22. const { RangePicker } = DatePicker;
  23. const App = () => {
  24. const [loading, setLoading] = React.useState(true);
  25. const [estDisabled, setEstDisabled] = React.useState(false);
  26. const [grupos, setGrupos] = React.useState([]);
  27. const [estaciones, setEstaciones] = React.useState([]);
  28. const [estacion, setEstacion] = React.useState(null);
  29. const [modalVisible, setModalVisible] = React.useState(false);
  30. const [reiniciar, setReiniciar] = React.useState(false);
  31. const [data, setData] = React.useState([]);
  32. const [debug, setDebug] = React.useState(null);
  33. const [form] = Form.useForm();
  34. const loadingIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
  35. let obtenerGrupos = async () => {
  36. const resp = await fetch(`${url}/na/grupo`)
  37. const json = await resp.json();
  38. setLoading(false);
  39. setGrupos(json.resultado);
  40. }
  41. React.useEffect(() => {
  42. obtenerGrupos();
  43. }, []);
  44. const onCityChange = async (id) => {
  45. setEstDisabled(true);
  46. const resp = await fetch(`${url}/na/grupo?id=${id}&expand=ciudades.monitoreable&ordenar=nombre`)
  47. const json = await resp.json();
  48. let ciudad = json.resultado[0].ciudades[0];
  49. let _estaciones = [];
  50. for(let estacion of ciudad.monitoreable) {
  51. _estaciones.push({
  52. "idCiudad": ciudad.id,
  53. "idEstacion": estacion.id,
  54. "clave": estacion.clave,
  55. "frecuencia": estacion.frecuencia,
  56. "siglas": estacion.siglas
  57. })
  58. }
  59. setEstaciones(_estaciones);
  60. setEstDisabled(false);
  61. }
  62. const onStationChange = async (id) => {
  63. for(let est of estaciones) {
  64. if(est.idEstacion == id) {
  65. setEstacion(est);
  66. break;
  67. }
  68. }
  69. }
  70. const confirmar = (f) => {
  71. let body = {
  72. idPc: f.idPc,
  73. fi: f.fechas[0].format(),
  74. ff: f.fechas[1].format(),
  75. reiniciar: reiniciar,
  76. estaciones: data
  77. }
  78. const fi = f.fechas[0].format("DD/MM/YYYY");
  79. const ff = f.fechas[1].format("DD/MM/YYYY");
  80. Modal.confirm({
  81. title: `¿Guardar ${body.estaciones.length} estaciones en PC "${body.idPc}" desde ${fi} hasta ${ff}?`,
  82. // content: <pre>{JSON.stringify(data)}</pre>,
  83. onOk: () => { handleOk(body) } ,
  84. });
  85. }
  86. const handleOk = async (cuerpo) => {
  87. let resp = await fetch(`/descarga/guardar`, {
  88. method: "POST",
  89. body: JSON.stringify(cuerpo),
  90. headers: {
  91. "Content-Type": "application/json"
  92. }
  93. });
  94. setDebug(cuerpo);
  95. // form.setFieldsValue({ idPc: '' });
  96. // setData([]);
  97. }
  98. const agregarEstacion = () => {
  99. if(estacion === null) {
  100. Modal.warning({
  101. title: 'No eligió una estación',
  102. content: 'Por favor seleccione una estación'
  103. });
  104. return;
  105. }
  106. const found = data.find(e => e.idEstacion === estacion.idEstacion);
  107. if(found) {
  108. Modal.warning({
  109. title: `La Estación ${estacion.siglas} ya se encuentra en la lista`
  110. });
  111. return;
  112. }
  113. let _data = [...data];
  114. _data.push({
  115. key: `${estacion.idCiudad}-${estacion.idEstacion}`,
  116. ...estacion,
  117. });
  118. form.setFieldsValue({ idEstacion: null })
  119. setEstacion(null);
  120. setData(_data);
  121. return;
  122. }
  123. const obtenerEstacionDelPC = async () => {
  124. let idPc = form.getFieldValue('idPc');
  125. if(!idPc) {
  126. Modal.warning({
  127. title: 'No eligió un PC',
  128. content: 'Por favor seleccione un PC'
  129. });
  130. return;
  131. }
  132. let resp = await fetch(`/estacion/por-pc?pc=${idPc}`);
  133. let data = await resp.json();
  134. setData(data.resultado);
  135. }
  136. const eliminar = (key) => {
  137. const _data = [...data];
  138. setData(_data.filter(item => item.key !== key) );
  139. }
  140. const columnas = [
  141. {
  142. title: 'ID Ciudad',
  143. dataIndex: 'idCiudad',
  144. key: '1',
  145. },
  146. {
  147. title: 'Clave',
  148. dataIndex: 'clave',
  149. key: '2',
  150. },
  151. {
  152. title: 'Eliminar',
  153. key: '3',
  154. render(r) {
  155. return (
  156. <Popconfirm
  157. title="¿Eliminar?"
  158. okText="OK"
  159. cancelText="Cancelar"
  160. onConfirm={() => eliminar(r.key)}>
  161. <a>Eliminar</a>
  162. </Popconfirm>
  163. )
  164. }
  165. }
  166. ];
  167. return (
  168. <div className="site-card">
  169. { loading
  170. ? <Spin indicator={loadingIcon} />
  171. : <Card className="content">
  172. <Form
  173. form={form}
  174. layout="vertical"
  175. onFinish={confirmar}
  176. >
  177. <Row gutter={8}>
  178. <Col span={6}>
  179. <Form.Item
  180. label="ID PC"
  181. name="idPc"
  182. rules={[{ required: true, message: 'Ingresa el ID del PC' }]}
  183. >
  184. <Input size="large" />
  185. </Form.Item>
  186. </Col>
  187. <Col span={6}>
  188. <Form.Item
  189. label="Rango de Fechas"
  190. name="fechas"
  191. rules={[{ required: true, message: 'Ingresa el Rango de Fechas' }]}
  192. >
  193. <RangePicker
  194. showTime={{
  195. hideDisabledOptions: true,
  196. defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  197. }}
  198. format="DD-MM-YYYY HH:mm:ss"
  199. size="large"
  200. />
  201. </Form.Item>
  202. </Col>
  203. <Col span={6}>
  204. <Form.Item
  205. label="&nbsp;"
  206. name="reiniciar"
  207. >
  208. <Checkbox size="large" checked={reiniciar} onChange={(e) => { setReiniciar(e.target.checked) }}>
  209. ¿Reiniciar descargas?
  210. </Checkbox>
  211. </Form.Item>
  212. </Col>
  213. </Row>
  214. <Row gutter={8}>
  215. <Col span={6}>
  216. <Form.Item
  217. label="Ciudad"
  218. name="idCiudad"
  219. >
  220. <Select
  221. showSearch
  222. size="large"
  223. style={{ width: '100%' }}
  224. placeholder="Elige un grupo"
  225. optionFilterProp="children"
  226. onChange={onCityChange}
  227. filterOption={(input, option) =>
  228. option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
  229. }
  230. >
  231. { grupos && grupos.map((item) => { return <Option key={`grupo-${item.id}`} value={item.id}>{item.nombre}</Option> }) }
  232. </Select>
  233. </Form.Item>
  234. </Col>
  235. <Col span={6}>
  236. <Form.Item
  237. label="Estación"
  238. name="idEstacion"
  239. >
  240. <Select
  241. disabled={estDisabled}
  242. showSearch
  243. size="large"
  244. style={{ width: '100%' }}
  245. placeholder="Elige una estación"
  246. optionFilterProp="children"
  247. onChange={onStationChange}
  248. filterOption={(input, option) =>
  249. option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
  250. }
  251. >
  252. { estaciones && estaciones.map((item) => { return <Option key={`est-${item.idEstacion}`} value={item.idEstacion}>{item.frecuencia} - {item.siglas} - {item.clave}</Option> }) }
  253. </Select>
  254. </Form.Item>
  255. </Col>
  256. <Col span={3}>
  257. <Form.Item label="&nbsp;" >
  258. <Button className="full-width" size="large" onClick={agregarEstacion}>Agregar</Button>
  259. </Form.Item>
  260. </Col>
  261. </Row>
  262. <Row gutter={8}>
  263. <Col span={12}>
  264. <Table className="full-width" dataSource={data} columns={columnas} />
  265. </Col>
  266. <Col span={3}>
  267. <Button className="full-width" size="large" onClick={obtenerEstacionDelPC}>Estaciones del PC</Button>
  268. </Col>
  269. </Row>
  270. <Row>
  271. <Col span={6}>
  272. <Form.Item label="&nbsp;" >
  273. <Button type="primary" htmlType="submit" size="large" style={{width: '100%'}}>Guardar</Button>
  274. </Form.Item>
  275. </Col>
  276. </Row>
  277. </Form>
  278. <Row>
  279. <Col className="full-width">
  280. {debug && <pre className="full-width">{JSON.stringify(debug)}</pre>}
  281. </Col>
  282. </Row>
  283. </Card>
  284. }
  285. </div>
  286. );
  287. }
  288. ReactDOM.render(<App />, document.getElementById('root'));
  289. </script>