merge with branch master before merge
241
package-lock.json
generated
@ -22622,15 +22622,6 @@
|
||||
"@hapi/hoek": "^8.3.0"
|
||||
}
|
||||
},
|
||||
"@hypnosphi/create-react-context": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz",
|
||||
"integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==",
|
||||
"requires": {
|
||||
"gud": "^1.0.0",
|
||||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
@ -23188,9 +23179,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
@ -28261,9 +28252,9 @@
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz",
|
||||
"integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA=="
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
@ -28646,11 +28637,6 @@
|
||||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
||||
"optional": true
|
||||
},
|
||||
"gud": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
|
||||
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
|
||||
},
|
||||
"gzip-size": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
|
||||
@ -29049,114 +29035,6 @@
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
|
||||
"integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
|
||||
"requires": {
|
||||
"http-proxy": "^1.17.0",
|
||||
"is-glob": "^4.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"micromatch": "^3.1.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"braces": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
||||
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
||||
"requires": {
|
||||
"arr-flatten": "^1.1.0",
|
||||
"array-unique": "^0.3.2",
|
||||
"extend-shallow": "^2.0.1",
|
||||
"fill-range": "^4.0.0",
|
||||
"isobject": "^3.0.1",
|
||||
"repeat-element": "^1.1.2",
|
||||
"snapdragon": "^0.8.1",
|
||||
"snapdragon-node": "^2.0.1",
|
||||
"split-string": "^3.0.2",
|
||||
"to-regex": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-number": "^3.0.0",
|
||||
"repeat-string": "^1.6.1",
|
||||
"to-regex-range": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"kind-of": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
"integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
"braces": "^2.3.1",
|
||||
"define-property": "^2.0.2",
|
||||
"extend-shallow": "^3.0.2",
|
||||
"extglob": "^2.0.4",
|
||||
"fragment-cache": "^0.2.1",
|
||||
"kind-of": "^6.0.2",
|
||||
"nanomatch": "^1.2.9",
|
||||
"object.pick": "^1.3.0",
|
||||
"regex-not": "^1.0.0",
|
||||
"snapdragon": "^0.8.1",
|
||||
"to-regex": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
|
||||
"integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"repeat-string": "^1.6.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
@ -32963,6 +32841,11 @@
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
|
||||
},
|
||||
"pigeon-maps": {
|
||||
"version": "0.19.7",
|
||||
"resolved": "https://registry.npmjs.org/pigeon-maps/-/pigeon-maps-0.19.7.tgz",
|
||||
"integrity": "sha512-8yS5o7lr3mr5674Cfkxrk3EqPiV6WjGBrpVKNn6/40bTdH5qq2NNXK2Iu0fQcDRRZ6mTtXHX0tJAO1tp8ZKBNg=="
|
||||
},
|
||||
"pinkie": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
|
||||
@ -33072,11 +32955,6 @@
|
||||
"ts-pnp": "^1.1.6"
|
||||
}
|
||||
},
|
||||
"popper.js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
|
||||
},
|
||||
"portfinder": {
|
||||
"version": "1.0.28",
|
||||
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
|
||||
@ -33103,9 +32981,9 @@
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
|
||||
},
|
||||
"postcss": {
|
||||
"version": "7.0.35",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
|
||||
"integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
|
||||
"version": "7.0.36",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
|
||||
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"source-map": "^0.6.1",
|
||||
@ -34783,18 +34661,6 @@
|
||||
"whatwg-fetch": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"react-datepicker": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz",
|
||||
"integrity": "sha512-iFVNEp8DJoX5yEvEiciM7sJKmLGrvE70U38KhpG13XrulNSijeHw1RZkhd/0UmuXR71dcZB/kdfjiidifstZjw==",
|
||||
"requires": {
|
||||
"classnames": "^2.2.6",
|
||||
"date-fns": "^2.0.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-onclickoutside": "^6.10.0",
|
||||
"react-popper": "^1.3.8"
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "11.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz",
|
||||
@ -34921,25 +34787,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"react-onclickoutside": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.10.0.tgz",
|
||||
"integrity": "sha512-7i2L3ef+0ILXpL6P+Hg304eCQswh4jl3ynwR71BSlMU49PE2uk31k8B2GkP6yE9s2D4jTGKnzuSpzWxu4YxfQQ=="
|
||||
},
|
||||
"react-popper": {
|
||||
"version": "1.3.11",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz",
|
||||
"integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@hypnosphi/create-react-context": "^0.3.1",
|
||||
"deep-equal": "^1.1.1",
|
||||
"popper.js": "^1.14.4",
|
||||
"prop-types": "^15.6.1",
|
||||
"typed-styles": "^0.0.7",
|
||||
"warning": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"react-refresh": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
||||
@ -35443,9 +35290,9 @@
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||
},
|
||||
"resolve-url-loader": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz",
|
||||
"integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==",
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz",
|
||||
"integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==",
|
||||
"requires": {
|
||||
"adjust-sourcemap-loader": "3.0.0",
|
||||
"camelcase": "5.3.1",
|
||||
@ -35453,7 +35300,7 @@
|
||||
"convert-source-map": "1.7.0",
|
||||
"es6-iterator": "2.0.3",
|
||||
"loader-utils": "1.2.3",
|
||||
"postcss": "7.0.21",
|
||||
"postcss": "7.0.36",
|
||||
"rework": "1.0.1",
|
||||
"rework-visit": "1.0.0",
|
||||
"source-map": "0.6.1"
|
||||
@ -35487,28 +35334,10 @@
|
||||
"json5": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"version": "7.0.21",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz",
|
||||
"integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==",
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
"source-map": "^0.6.1",
|
||||
"supports-color": "^6.1.0"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
|
||||
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -37211,9 +37040,9 @@
|
||||
}
|
||||
},
|
||||
"trim-newlines": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz",
|
||||
"integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
|
||||
"integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
|
||||
"dev": true
|
||||
},
|
||||
"tryer": {
|
||||
@ -37310,11 +37139,6 @@
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"typed-styles": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
|
||||
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
@ -38429,6 +38253,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
|
||||
"integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
|
||||
"requires": {
|
||||
"http-proxy": "^1.17.0",
|
||||
"is-glob": "^4.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"micromatch": "^3.1.10"
|
||||
}
|
||||
},
|
||||
"import-local": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
|
||||
@ -38652,9 +38487,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
|
||||
"integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
@ -39110,9 +38945,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
|
||||
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
|
||||
"integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg=="
|
||||
},
|
||||
"xml-name-validator": {
|
||||
"version": "3.0.0",
|
||||
|
@ -14,10 +14,9 @@
|
||||
"chartjs-plugin-datalabels": "^2.0.0-rc.1",
|
||||
"chartjs-plugin-zoom": "^1.1.1",
|
||||
"craco-less": "^1.17.1",
|
||||
"date-fns": "^2.20.0",
|
||||
"moment": "^2.29.1",
|
||||
"pigeon-maps": "^0.19.7",
|
||||
"react": "^17.0.2",
|
||||
"react-datepicker": "^3.8.0",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "4.0.3",
|
||||
|
@ -6,16 +6,6 @@
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
|
@ -8,7 +8,7 @@ import Main from './pages/Main'
|
||||
import { OpenAPI } from './services/api'
|
||||
import { PrivateRoute } from './components/PrivateRoute'
|
||||
|
||||
OpenAPI.BASE = 'http://localhost:3000'
|
||||
//OpenAPI.BASE = 'http://localhost:3000'
|
||||
OpenAPI.TOKEN = localStorage['token']
|
||||
|
||||
export default function App() {
|
||||
|
106
src/components/CementFluid.jsx
Normal file
@ -0,0 +1,106 @@
|
||||
let date = new Date().toLocaleString()
|
||||
|
||||
export function CementFluid() {
|
||||
return (<>
|
||||
<table>
|
||||
<thead style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "800px", fontWeight: "800", textAlign: "center"}}>
|
||||
<tr>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>
|
||||
<b>Наименование</b></td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Температура, °C</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Плотность, г/см³</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Усл. вязкость, сек</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>R300</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>R600</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>R3/R6</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>ДНС, дПа</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Пластич. вязкость, сПз</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>СНС, дПа</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>R3/R6 49С</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>ДНС 49С, дПа</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Пластич. вязкость 49С, сПз</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>СНС 49С, дПа</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>МВТ, кг/м³</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Песок, %</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Фильтрация, см³/30мин</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Корка, мм</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>КТК</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>рН</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Жесткость, мг/л</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Хлориды, мг/л</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Pf</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Mf</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Pm</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Твердая фаза раствора, %</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Смазка, %</td>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}>Карбонат кальция, кг/м³</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "400", textAlign: "center"}}>
|
||||
<tr>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800", textAlign: "center"}}><b>План</b></td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{borderTop:"2px solid", borderLeft: "2px solid", borderRight: "2px solid", borderBottom: "2px solid", width: "66px", fontWeight: "800"}}><b>Факт</b></td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
<td style={{borderTop:"1px solid", borderLeft: "1px solid", borderRight: "1px solid", borderBottom: "1px solid", width: "66px", fontWeight: "400", textAlign: "center"}}> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div> </div>
|
||||
<p style={{textAlign: "right"}}><b>{date}</b></p>
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,26 +1,34 @@
|
||||
import {Display} from './Display'
|
||||
import RigMnemo from '../components/RigMnemo'
|
||||
|
||||
const params = [
|
||||
{label:'Рот., об/мин', accessorName:'rotorSpeed', isArrowVisible:true},
|
||||
{label:'Долото, м', accessorName:'bitDepth', isArrowVisible:true, format:2},
|
||||
{label:'Забой, м', accessorName:'wellDepth', isArrowVisible:true, format:2},
|
||||
{label:'Расход, м³/ч', accessorName:'flow', isArrowVisible:true},
|
||||
{label:'Расход х.х., м³/ч', accessorName:'flowIdle', isArrowVisible:true},
|
||||
{label: 'Время', accessorName: 'date', format:'HH:mm:ss'},
|
||||
]
|
||||
|
||||
export const CustomColumn = ({data}) => {
|
||||
const dataLast = data[data.length -1]
|
||||
|
||||
const lines = [
|
||||
{label:'Рот., об/мин', accessorName:'rotorSpeed'},
|
||||
{label:'Долото, м', accessorName:'bitDepth'},
|
||||
{label:'Забой, м', accessorName:'wellDepth'},
|
||||
{label:'Расход, м³/ч', accessorName:'flow'},
|
||||
{label:'Расход х.х., м³/ч', accessorName:'flowIdle'},
|
||||
]
|
||||
|
||||
if(dataLast)
|
||||
lines.forEach(line => line.value = dataLast[line.accessorName]?.toPrecision(4)??'-' )
|
||||
params.forEach(param => param.value = dataLast[param.accessorName])
|
||||
else
|
||||
lines.forEach(line => line.value = '-' )
|
||||
params.forEach(param => param.value = '-' )
|
||||
|
||||
return (<>
|
||||
{lines.map(line => <Display className='border_small display_flex_container'
|
||||
key={line.label}
|
||||
label={line.label}
|
||||
value={line.value}
|
||||
suffix={line.units}/>)}
|
||||
{params.map(param => <Display className='border_small display_flex_container'
|
||||
key={param.label}
|
||||
label={param.label}
|
||||
value={param.value}
|
||||
suffix={param.units}
|
||||
isArrowVisible = {param.isArrowVisible}
|
||||
format = {param.format}
|
||||
/>)}
|
||||
<RigMnemo
|
||||
blockPosition={dataLast?.blockPosition??0}
|
||||
bitPosition={dataLast?.bitDepth??3200}/>
|
||||
</>)
|
||||
}
|
@ -1,43 +1,70 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import {CaretUpOutlined, CaretDownOutlined} from '@ant-design/icons'
|
||||
import {CaretUpOutlined, CaretDownOutlined, CaretRightOutlined} from '@ant-design/icons'
|
||||
import moment from 'moment';
|
||||
|
||||
export const ValueDisplay = ({prefix, value, suffix, isArrowVisible}) =>{
|
||||
const [oldVal, setOldVal] = useState(NaN)
|
||||
export const formatNumber = (value, format) =>
|
||||
Number.isInteger(format) && Number.isFinite(value)
|
||||
? (+value).toFixed(format)
|
||||
: (+value).toPrecision(4)
|
||||
|
||||
export const ValueDisplay = ({prefix, value, suffix, isArrowVisible, format}) =>{
|
||||
const [val, setVal] = useState('---')
|
||||
const [arrowState, setArrowState] = useState(0)
|
||||
const [arrowState, setArrowState] = useState({
|
||||
preVal: NaN,
|
||||
preTimestamp: Date.now(),
|
||||
direction: 0,
|
||||
})
|
||||
|
||||
useEffect(()=>{
|
||||
if(value){
|
||||
if(Number.isFinite(+value)){
|
||||
if (isArrowVisible)
|
||||
{
|
||||
let newArrowState = 0
|
||||
if (value > oldVal)
|
||||
newArrowState = 1
|
||||
if (value < oldVal)
|
||||
newArrowState = -1
|
||||
setArrowState(newArrowState)
|
||||
setOldVal(value)
|
||||
}
|
||||
setVal((+value).toPrecision(4)??'---')
|
||||
}
|
||||
else
|
||||
setVal(value)
|
||||
if(value === undefined || value === null){
|
||||
setVal('---')
|
||||
return
|
||||
}
|
||||
|
||||
},[value, isArrowVisible, oldVal])
|
||||
if(Number.isFinite(+value)){
|
||||
if ((isArrowVisible) && (arrowState.preTimestamp + 1000 < Date.now()))
|
||||
{
|
||||
let direction = 0
|
||||
if (value > arrowState.preVal)
|
||||
direction = 1
|
||||
if (value < arrowState.preVal)
|
||||
direction = -1
|
||||
|
||||
setArrowState({
|
||||
preVal: value,
|
||||
preTimestamp: Date.now(),
|
||||
direction: direction,
|
||||
})
|
||||
}
|
||||
|
||||
setVal(formatNumber(value, format))
|
||||
return
|
||||
}
|
||||
|
||||
let valueDate = moment(value)
|
||||
if(valueDate.isValid()){
|
||||
setVal(valueDate.format(format))
|
||||
return
|
||||
}
|
||||
|
||||
setVal(value)
|
||||
},[value, isArrowVisible, arrowState, format])
|
||||
|
||||
let arrow = null
|
||||
switch (arrowState){
|
||||
case 1:
|
||||
arrow = <CaretUpOutlined style={{color:"red"}}/>
|
||||
break
|
||||
case -1:
|
||||
arrow = <CaretDownOutlined style={{color:"red"}}/>
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
if(isArrowVisible)
|
||||
switch (arrowState.direction){
|
||||
case 0:
|
||||
arrow = <CaretRightOutlined style={{color:"#0008"}}/>
|
||||
break
|
||||
case 1:
|
||||
arrow = <CaretUpOutlined style={{color:"#0008"}}/>
|
||||
break
|
||||
case -1:
|
||||
arrow = <CaretDownOutlined style={{color:"#0008"}}/>
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return(<span className='display_value'>{prefix} {val} {suffix}{arrow}</span>)
|
||||
}
|
||||
|
19
src/components/Disposition.jsx
Normal file
@ -0,0 +1,19 @@
|
||||
let date = new Date().toLocaleString()
|
||||
|
||||
|
||||
export default function Disposition() {
|
||||
return (
|
||||
<>
|
||||
<h1 style={{textAlign: "center"}}>Распоряжение</h1>
|
||||
|
||||
<p style={{textAlign: "justify"}}>
|
||||
Текст
|
||||
</p>
|
||||
|
||||
<p style={{textAlign: "right"}}><i>Ф.И.О.</i></p>
|
||||
<p style={{textAlign: "right"}}><i>Должность</i></p>
|
||||
<p style={{textAlign: "right"}}><i>Компания</i></p>
|
||||
<p style={{textAlign: "right"}}><b>{date}</b></p>
|
||||
</>
|
||||
)
|
||||
}
|
230
src/components/Documents.jsx
Normal file
@ -0,0 +1,230 @@
|
||||
import {Table, DatePicker, Form, Button, Upload, ConfigProvider} from 'antd'
|
||||
import { UploadOutlined } from '@ant-design/icons'
|
||||
import MenuDocuments from "./MenuDocuments"
|
||||
import { FileService } from '../services/api'
|
||||
import {useState, useEffect} from "react"
|
||||
import {useParams} from 'react-router-dom'
|
||||
import notify from './notify'
|
||||
import LoaderPortal from './LoaderPortal'
|
||||
import locale from "antd/lib/locale/ru_RU"
|
||||
import moment from 'moment'
|
||||
|
||||
const pageSize = 12
|
||||
const {RangePicker} = DatePicker;
|
||||
|
||||
|
||||
export default function Documents({selectedFileCategory}) {
|
||||
let {id} = useParams()
|
||||
|
||||
const [page, setPage] = useState(1)
|
||||
const [range, setRange] = useState([])
|
||||
const [pagination, setPagination] = useState(null)
|
||||
const [files, setFiles] = useState([])
|
||||
const [selectedFiles, setSelectedFiles] = useState([])
|
||||
const [isTableUpdating, setTableUpdating] = useState(false)
|
||||
|
||||
const [loader, setLoader] = useState(false)
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const handleFileNameCLick = async (event, row) => {
|
||||
const element = event.target
|
||||
|
||||
if(!element.href.length) {
|
||||
try {
|
||||
setLoader(true)
|
||||
|
||||
await fetch(`/api/files/${id}/${row.id}`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + localStorage['token']
|
||||
}
|
||||
})
|
||||
.then(async (response) => {
|
||||
const blob = await response.blob();
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onload = function (e) {
|
||||
element.href = e.target.result
|
||||
element.click()
|
||||
};
|
||||
setLoader(false)
|
||||
});
|
||||
} catch (error) {
|
||||
notify(`Не удалось скачать файл ${row}`, 'error')
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Документ',
|
||||
key: 'document',
|
||||
dataIndex: 'name',
|
||||
render: (name, row) =>
|
||||
<a onClick={ev => handleFileNameCLick(ev, row)} download={name}>{name}</a>
|
||||
},
|
||||
{
|
||||
title: 'Дата загрузки',
|
||||
key: 'uploadDate',
|
||||
dataIndex: 'uploadDate',
|
||||
render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss')
|
||||
},
|
||||
{
|
||||
title: 'Ф.И.О.',
|
||||
key: 'userName',
|
||||
dataIndex: 'userName',
|
||||
}
|
||||
];
|
||||
|
||||
const submitFileFormProps = {
|
||||
progress: {
|
||||
strokeColor: {
|
||||
'0%': '#108ee9',
|
||||
'100%': '#87d068',
|
||||
},
|
||||
strokeWidth: 3,
|
||||
format: percent => `${parseFloat(percent.toFixed(2))}%`,
|
||||
},
|
||||
onChange({ file, fileList }) {
|
||||
if (file.status !== 'uploading') {
|
||||
setSelectedFiles(fileList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onChangeRange = (range) => {
|
||||
setRange(range)
|
||||
}
|
||||
|
||||
const onFinish = (values, form) => {
|
||||
var fileList = values.fileInput.fileList
|
||||
|
||||
if (fileList.length > 0)
|
||||
{
|
||||
setLoader(true)
|
||||
const formData = new FormData();
|
||||
|
||||
fileList.forEach(val => {
|
||||
formData.append('files', val.originFileObj)
|
||||
})
|
||||
|
||||
fetch(`/api/files/${id}/files?idCategory=${selectedFileCategory}&idUser=${localStorage['userId']}`, {
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + localStorage['token']
|
||||
},
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(async (response) => {
|
||||
setLoader(false)
|
||||
form.resetFields()
|
||||
setTableUpdating(true)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const onFinishFailed = (errorInfo) => {
|
||||
notify(`Не удалось отправить файлы по скважине "${id}".`, 'error')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const GetDocuments = async () => {
|
||||
setLoader(true)
|
||||
|
||||
try {
|
||||
let begin = null
|
||||
let end = null
|
||||
if (range?.length > 1) {
|
||||
begin = range[0].toISOString()
|
||||
end = range[1].toISOString()
|
||||
}
|
||||
|
||||
await FileService.getFilesInfo(
|
||||
`${id}`,
|
||||
(page - 1) * pageSize,
|
||||
pageSize,
|
||||
selectedFileCategory,
|
||||
begin,
|
||||
end
|
||||
).then((paginatedFiles) => {
|
||||
setFiles(paginatedFiles?.items.map(f => {
|
||||
return {
|
||||
key: f.id,
|
||||
begin: f.date,
|
||||
...f
|
||||
}
|
||||
}))
|
||||
|
||||
setPagination({
|
||||
total: paginatedFiles?.count,
|
||||
current: Math.floor(paginatedFiles?.skip / pageSize),
|
||||
})
|
||||
|
||||
setTableUpdating(false)
|
||||
setLoader(false)
|
||||
}
|
||||
)
|
||||
} catch (ex) {
|
||||
notify(`Не удалось загрузить файлы по скважине "${id}"`, 'error')
|
||||
console.log(ex)
|
||||
}
|
||||
}
|
||||
GetDocuments()
|
||||
}, [id, range,page, selectedFileCategory, isTableUpdating])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MenuDocuments/>
|
||||
<div className='filter-group'>
|
||||
<h3 className='filter-group-heading'>Фильтр документов:</h3>
|
||||
<ConfigProvider locale={locale}>
|
||||
<RangePicker
|
||||
showTime
|
||||
onChange={onChangeRange}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
<LoaderPortal show={loader}></LoaderPortal>
|
||||
<div> </div>
|
||||
<Form
|
||||
form={form}
|
||||
name="DocumentsUploadForm"
|
||||
onFinish={(values) => onFinish(values, form)}
|
||||
onFinishFailed={onFinishFailed}
|
||||
style={{width: '300px'}}
|
||||
>
|
||||
<Form.Item
|
||||
name="fileInput"
|
||||
rules={[{ required: true, message: 'Выберите файл' }]}
|
||||
>
|
||||
<Upload {...submitFileFormProps}>
|
||||
<Button icon={<UploadOutlined />}>Загрузить файл</Button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
disabled={selectedFiles.length === 0}
|
||||
>
|
||||
Отправить
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div> </div>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={files}
|
||||
size={'small'}
|
||||
pagination={{
|
||||
pageSize: pageSize,
|
||||
showSizeChanger: false,
|
||||
total: pagination?.total,
|
||||
current: page,
|
||||
onChange: (page) => setPage(page)
|
||||
}}
|
||||
rowKey={(record) => record.id}
|
||||
/>
|
||||
</div>);
|
||||
}
|
20
src/components/LayoutPortal.jsx
Normal file
@ -0,0 +1,20 @@
|
||||
import {Layout} from 'antd'
|
||||
import PageHeader from './PageHeader'
|
||||
|
||||
const {Content} = Layout
|
||||
|
||||
export default function LayoutPortal({title, noSheet, children}) {
|
||||
const content = noSheet
|
||||
? <Layout>{children}</Layout>
|
||||
: <Layout>
|
||||
<Content className="site-layout-background sheet">
|
||||
{children}
|
||||
</Content>
|
||||
</Layout>
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<PageHeader title={title}/>
|
||||
{content}
|
||||
</Content>)
|
||||
}
|
50
src/components/MenuDocuments.jsx
Normal file
@ -0,0 +1,50 @@
|
||||
import {Menu} from "antd";
|
||||
import {FolderOutlined} from "@ant-design/icons";
|
||||
import {Link} from "react-router-dom";
|
||||
import {useState} from "react"
|
||||
|
||||
|
||||
export default function MenuDocuments() {
|
||||
|
||||
const [selectedItem, setSelectedItem] = useState(1)
|
||||
|
||||
const handleClick = e => {
|
||||
setSelectedItem({ current: e.key });
|
||||
};
|
||||
|
||||
return(
|
||||
<>
|
||||
<Menu
|
||||
mode="horizontal"
|
||||
selectable={true}
|
||||
className="well_menu"
|
||||
onClick={handleClick}
|
||||
selectedKeys={[selectedItem]}
|
||||
>
|
||||
<Menu.Item key="1" icon={<FolderOutlined/>}>
|
||||
<Link to='fluidService'>Растворный сервис</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2" icon={<FolderOutlined/>}>
|
||||
<Link to='cementing'>Цементирование</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="3" icon={<FolderOutlined/>}>
|
||||
<Link to='nnb'>ННБ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="4" icon={<FolderOutlined/>}>
|
||||
<Link to='gti'>ГТИ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="5" icon={<FolderOutlined/>}>
|
||||
<Link to='documentsForWell'>Документы по скважине</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="6" icon={<FolderOutlined/>}>
|
||||
<Link to='supervisor'>Супервайзер</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="7" icon={<FolderOutlined/>}>
|
||||
<Link to='master'>Мастер</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="8" icon={<FolderOutlined/>}>
|
||||
<Link to='lastData'>Последние данные</Link>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</>)
|
||||
}
|
250
src/components/NnbTable.jsx
Normal file
@ -0,0 +1,250 @@
|
||||
let date = new Date().toLocaleString()
|
||||
|
||||
export function NnbTable() {
|
||||
return (<>
|
||||
<table cellspacing="0" border="0">
|
||||
<colGroup span="18" width="79"></colGroup>
|
||||
<tr>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} height="91" align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma"
|
||||
size="2">Глубина по
|
||||
стволу, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Зенитный
|
||||
угол, град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Азимут
|
||||
магнитный, град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Азимут
|
||||
истинный, град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Азимут
|
||||
дирекц., град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Глубина по
|
||||
вертикали, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Абсолютная
|
||||
отметка, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Лок.
|
||||
смещение к северу, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Лок.
|
||||
смещение к востоку, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Отклонение
|
||||
от устья, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Азимут
|
||||
смещения, град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Отклонение
|
||||
от устья, м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,000"><font face="Tahoma" size="2">Пространст.
|
||||
интенсивность, град/10 м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Угол
|
||||
установки отклон., град</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;0,00"><font face="Tahoma" size="2">Интенсив.
|
||||
по зениту, град/10 м</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9" sdnum="1049;0;@"><font face="Tahoma"
|
||||
size="2">Комментарий</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9"><font face="Tahoma" size="2">Разница вертикальных глубин
|
||||
между ХХХ (план) и ХХХ (факт)</font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "2px solid #000000"
|
||||
}} align="center" valign="middle" bgcolor="#E2F0D9"><font face="Tahoma" size="2">Расстояние в пространстве между
|
||||
ХХХ (план) и ХХХ (факт)</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} height="25" align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="bottom"><font face="Arial Cyr"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle" sdnum="1049;0;0,00"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="middle"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="bottom"><font face="Tahoma" size="2"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000"
|
||||
}} align="center" valign="bottom"><font face="Tahoma" size="2"><br/></font></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div> </div>
|
||||
<p style={{textAlign: "right"}}><b>{date}</b></p>
|
||||
</>)
|
||||
}
|
@ -2,7 +2,7 @@ import { Layout, Button } from 'antd'
|
||||
import { UserOutlined } from '@ant-design/icons'
|
||||
import logo from '../images/logo_32.png'
|
||||
import { Link } from "react-router-dom"
|
||||
import WellTreeSelector from '../components/WellTreeSelector'
|
||||
import WellTreeSelector from './WellTreeSelector'
|
||||
|
||||
const { Header } = Layout
|
||||
|
||||
@ -17,10 +17,11 @@ export default function PageHeader({title='Мониторинг', wellsList}){
|
||||
return(
|
||||
<Layout>
|
||||
<Header className="header">
|
||||
<img src={logo} alt="АСБ" className="logo"/>
|
||||
<Link to="/" >
|
||||
<img src={logo} alt="АСБ" className="logo"/>
|
||||
</Link>
|
||||
<WellTreeSelector wellsList={wellsList}/>
|
||||
<h1 className="title">{title}</h1>
|
||||
<div> </div>
|
||||
<Link to="/login" onClick={handleLogout}>
|
||||
<Button icon={<UserOutlined/>}>
|
||||
({login}) Выход
|
184
src/components/RigMnemo.jsx
Normal file
@ -0,0 +1,184 @@
|
||||
const styleBase = {
|
||||
stroke: "none",
|
||||
strokeLinecap: "butt",
|
||||
strokeLinejoin: "miter",
|
||||
}
|
||||
|
||||
const styleCasing = {
|
||||
...styleBase,
|
||||
fill: "#808080",
|
||||
};
|
||||
const styleGround = {
|
||||
...styleBase,
|
||||
fill: "#deaa87",
|
||||
};
|
||||
|
||||
const styleTower = {
|
||||
...styleBase,
|
||||
fill: "#999999",
|
||||
};
|
||||
|
||||
const styleWell = {
|
||||
...styleBase,
|
||||
fill: "#37abc8",
|
||||
};
|
||||
|
||||
const styleBitDrive = {
|
||||
...styleBase,
|
||||
fill: "#ff8080",
|
||||
};
|
||||
|
||||
const styleBitTool = {
|
||||
...styleBase,
|
||||
fill: "#f9f9f9",
|
||||
};
|
||||
|
||||
const styleBlock = {
|
||||
...styleBase,
|
||||
fill: "#ffdd55",
|
||||
};
|
||||
|
||||
const stylePump1 = {
|
||||
...styleBase,
|
||||
fill: "#5fd35f",
|
||||
};
|
||||
|
||||
const stylePump2 = {
|
||||
...styleBase,
|
||||
fill: "#b3b3b3",
|
||||
};
|
||||
|
||||
export default function RigMnemo({
|
||||
blockPosition,
|
||||
bitPosition,
|
||||
}) {
|
||||
|
||||
let blockPositionLocal = +blockPosition
|
||||
blockPositionLocal = blockPositionLocal ? blockPositionLocal : 0
|
||||
const blockTranslate = `translate(-75, ${-35 + (50 * (30 - blockPositionLocal) / 30)})`
|
||||
|
||||
//let bitPositionLocal = +bitPosition
|
||||
//bitPositionLocal = bitPositionLocal ? bitPositionLocal : 0
|
||||
//const bitTranslate = `translate(0, ${-41 + 41 * (3426 - bitPosition)/(3426 - 3200)})`
|
||||
const bitTranslate = `translate(0, 0)`
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="400"
|
||||
height="540"
|
||||
viewBox="20 0 105.83333 145.52084"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
>
|
||||
<g id="Casing" style={styleCasing}>
|
||||
<path d="m 29.897917,67.46875 v -1.322917 l 4.497916,-10e-7 v -1.322916 h 3.96875 v 1.322916 l 4.497917,10e-7 v 1.322917 z" />
|
||||
<path d="M 31.75,97.895832 V 67.468749 h 9.260416 v 30.427083 z" />
|
||||
<path d="m 30.95625,83.34375 0,1.058333 h 10.847917 l -10e-7,-1.058333 z" />
|
||||
<path d="m 30.95625,85.195833 v 1.058333 h 10.847917 v -1.058333 z" />
|
||||
<path d="m 30.95625,70.114583 v 1.058333 h 10.847918 l -10e-7,-1.058333 z" />
|
||||
<path d="m 30.95625,71.966666 v 1.058333 h 10.847918 v -1.058333 z" />
|
||||
</g>
|
||||
<g id="Ground">
|
||||
<path
|
||||
style={styleGround}
|
||||
d="m 62.177083,83.34375 -19.84375,0 V 97.895833 H 39.6875 V 142.875 H 33.072917 V 97.895833 H 30.427083 V 83.34375 l -10.583333,0 v 62.17708 h 42.333333 z"
|
||||
id="path849"
|
||||
/>
|
||||
</g>
|
||||
<g id="Tower" style={styleTower}>
|
||||
<path d="m 29.104166,83.343749 v -2.645833 h -3.96875 v 2.645833 z" />
|
||||
<path d="m 43.656249,83.343749 v -2.645833 h 3.96875 v 2.645833 z" />
|
||||
<path d="m 26.458333,80.697916 v -11.90625 h 1.322917 v 11.90625 z" />
|
||||
<path d="m 44.979166,80.697917 v -11.90625 h 1.322917 v 11.90625 z" />
|
||||
<path d="m 22.489583,68.791666 h 27.78125 v -1.322917 h -27.78125 z" />
|
||||
<path d="M 22.357422 66.013672 L 22.357422 67.601562 L 22.490234 67.601562 L 50.402344 67.601562 L 50.402344 66.013672 L 50.271484 66.013672 C 47.662479 66.013673 45.393545 66.029632 41.142578 66.013672 L 40.878906 66.013672 L 31.882812 66.013672 L 31.75 66.013672 C 31.693076 66.013672 31.673038 66.013672 31.617188 66.013672 C 27.779098 66.013674 26.402061 66.013673 22.490234 66.013672 L 22.357422 66.013672 z M 22.621094 66.277344 C 26.405208 66.277345 27.834127 66.277346 31.617188 66.277344 L 31.617188 67.335938 L 22.621094 67.335938 L 22.621094 66.277344 z M 31.882812 66.277344 L 40.878906 66.277344 L 40.878906 67.335938 L 31.882812 67.335938 L 31.882812 66.277344 z M 41.142578 66.277344 C 45.330989 66.293059 47.579975 66.277812 50.138672 66.277344 L 50.138672 67.335938 L 41.142578 67.335938 L 41.142578 66.277344 z " />
|
||||
<path d="M 34.263672 2.5136719 L 34.263672 2.6464844 L 34.263672 6.7460938 L 38.496094 6.7460938 L 38.496094 2.5136719 L 34.263672 2.5136719 z M 34.527344 2.7773438 L 38.232422 2.7773438 L 38.232422 6.4824219 L 34.527344 6.4824219 L 34.527344 2.7773438 z " />
|
||||
<path d="m 34.395833,4.4979166 h 3.96875 v 0.2645833 h -3.96875 z" />
|
||||
<path d="M 36.247916,2.6458333 V 6.6145832 H 36.5125 V 2.6458333 Z" />
|
||||
<path d="M 34.395833,6.6145833 V 7.9375 h 3.96875 V 6.6145833 Z" />
|
||||
<path d="m 26.458333,68.791666 7.9375,-60.8541661 h 1.322917 l -7.9375,60.8541661 z" />
|
||||
<path d="m 44.979166,68.791666 -7.9375,-60.8541661 h 1.322917 l 7.9375,60.8541661 z" />
|
||||
<path d="M 42.333333,26.458333 H 30.427083 L 27.78125,25.135416 h 17.197916 z" />
|
||||
<path d="M 34.396484 18.388672 L 34.396484 18.652344 L 38.365234 18.652344 L 38.365234 18.388672 L 34.396484 18.388672 z " />
|
||||
<path d="M 34.925781 13.097656 L 34.925781 13.361328 L 37.835938 13.361328 L 37.835938 13.097656 L 34.925781 13.097656 z " />
|
||||
<path d="M 37.724609 13.15625 L 34.285156 18.449219 L 34.505859 18.59375 L 37.947266 13.300781 L 37.724609 13.15625 z " />
|
||||
<path d="M 35.841797 7.8886719 L 35.595703 7.9863281 L 37.712891 13.277344 L 37.958984 13.179688 L 35.841797 7.8886719 z " />
|
||||
<path d="M 34.501953 18.441406 L 34.291016 18.601562 L 39.318359 25.214844 L 39.527344 25.054688 L 34.501953 18.441406 z " />
|
||||
<path d="M 28.574219 62.044922 L 28.574219 62.308594 L 44.185547 62.308594 L 44.185547 62.044922 L 28.574219 62.044922 z " />
|
||||
<path d="M 29.369141 55.429688 L 29.369141 55.695312 L 43.392578 55.695312 L 43.392578 55.429688 L 29.369141 55.429688 z " />
|
||||
<g id="g985">
|
||||
<path d="m 42.333333,48.947917 -11.90625,-10e-7" />
|
||||
<path d="M 30.427734 48.816406 L 30.427734 49.080078 L 42.333984 49.080078 L 42.333984 48.816406 L 30.427734 48.816406 z " />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M 41.539583,42.333333 H 31.220833" />
|
||||
<path d="M 31.220703 42.201172 L 31.220703 42.464844 L 41.539062 42.464844 L 41.539062 42.201172 L 31.220703 42.201172 z " />
|
||||
</g>
|
||||
<path d="M 31.326172 42.253906 L 31.115234 42.414062 L 36.142578 49.027344 L 36.248047 49.080078 L 36.511719 49.080078 L 36.617188 49.027344 L 41.644531 42.414062 L 41.433594 42.253906 L 36.447266 48.816406 L 36.314453 48.816406 L 31.326172 42.253906 z " />
|
||||
<path d="M 33.460938 26.412109 L 33.212891 26.503906 L 36.15625 34.527344 L 36.605469 34.527344 L 39.546875 26.503906 L 39.298828 26.412109 L 36.419922 34.263672 L 36.339844 34.263672 L 33.460938 26.412109 z " />
|
||||
<path d="M 32.398438 34.335938 L 32.160156 34.455078 L 36.166016 42.464844 L 36.59375 42.464844 L 40.599609 34.455078 L 40.363281 34.335938 L 36.431641 42.201172 L 36.330078 42.201172 L 32.398438 34.335938 z " />
|
||||
<path d="M 30.527344 48.861328 L 30.328125 49.035156 L 36.1875 55.695312 L 36.572266 55.695312 L 42.433594 49.035156 L 42.234375 48.861328 L 36.453125 55.429688 L 36.308594 55.429688 L 30.527344 48.861328 z " />
|
||||
<path d="M 36.199219 55.429688 L 28.488281 62.076172 L 28.662109 62.277344 L 36.296875 55.695312 L 36.462891 55.695312 L 44.099609 62.277344 L 44.271484 62.076172 L 36.5625 55.429688 L 36.199219 55.429688 z " />
|
||||
<path d="M 32.279297 34.263672 L 32.279297 34.527344 L 40.480469 34.527344 L 40.480469 34.263672 L 32.279297 34.263672 z " />
|
||||
</g>
|
||||
<g id="Well" style={styleWell}>
|
||||
<path d="M 33.072916,97.895832 H 39.6875 V 142.875 h -6.614584 z" />
|
||||
</g>
|
||||
<g id="Bit"
|
||||
transform={bitTranslate}>
|
||||
<path
|
||||
style={styleBitDrive}
|
||||
d="m 33.072916,142.875 1.322917,-3.96875 h 3.96875 L 39.6875,142.875 h -6.614584"
|
||||
/>
|
||||
<path
|
||||
style={styleBitTool}
|
||||
d="m 34.395833,138.90625 v -3.96875 h 3.96875 v 3.96875 z"
|
||||
/>
|
||||
</g>
|
||||
<g id="Block"
|
||||
transform={blockTranslate}
|
||||
style={styleBlock}
|
||||
>
|
||||
<path d="m 111.125,45.772916 c 0,0 -0.79375,-1.102431 -0.79375,-1.322917 0,-0.220486 -0.0952,-0.338724 0,-0.529166 0.0952,-0.190442 0.29053,-0.433713 0.52917,-0.529167 0.23864,-0.09545 0.55512,-0.09545 0.79375,0 0.23863,0.09545 0.43394,0.338726 0.52916,0.529167 0.0952,0.190441 0,0.440972 0,0.529166 0,0.08819 -0.79375,1.322917 -0.79375,1.322917 z" />
|
||||
<path d="m 111.38958,45.772916 c 0,0 0.17047,0.398584 0.26459,0.529167 0.0941,0.130583 0.22384,0.166227 0.26458,0.264583 0.0407,0.09836 0.0328,0.390283 0,0.529167 -0.0328,0.138884 -0.10568,0.166378 -0.26458,0.264584 -0.1589,0.09821 -0.37027,0.09821 -0.52917,0 -0.1589,-0.09821 -0.23179,-0.1257 -0.26458,-0.264584 -0.0328,-0.138884 0,-0.529167 0,-0.529167 0,0 0.10568,0.430961 0.26458,0.529167 0.1589,0.09821 0.40444,0.124726 0.52917,0 0.12472,-0.124725 0.0576,-0.39007 0,-0.529167 -0.0576,-0.139097 -0.17047,-0.133999 -0.26459,-0.264583 -0.0941,-0.130584 -0.26458,-0.529167 -0.26458,-0.529167 z" />
|
||||
<path d="m 110.33125,47.360416 v 2.38125 l 0.79375,10e-7 v 0.529166 h -0.26458 V 50.8 l 1.32291,-10e-7 v -0.529166 h -0.26458 v -0.529167 l 0.79375,10e-7 v -2.38125 z" />
|
||||
</g>
|
||||
<g id="Pump1" transform="translate(-0.79375,2.6066667e-4)">
|
||||
<circle
|
||||
style={stylePump1}
|
||||
id="PumpCircle"
|
||||
cx="51.59375"
|
||||
cy="80.698891"
|
||||
r="1.984375"
|
||||
/>
|
||||
<path
|
||||
d="m 51.064583,81.492642 1e-6,-1.587499 1.322916,0.79375 v -10e-7 z"
|
||||
id="PumpTriangle"
|
||||
/>
|
||||
<path
|
||||
style={stylePump1}
|
||||
d="m 48.948828,78.052995 v 5.292056 h 0.13086 l 5.158984,-2.6e-4 v -5.292057 z m 0.263672,0.263672 4.7625,-2.61e-4 v 4.762761 l -4.7625,2.6e-4 z"
|
||||
id="PumpSquare"
|
||||
/>
|
||||
</g>
|
||||
<g id="Pump2" transform="translate(4.7625,-5.205e-4)">
|
||||
<circle
|
||||
style={stylePump2}
|
||||
id="PumpCircle"
|
||||
cx="51.59375"
|
||||
cy="80.698891"
|
||||
r="1.984375"
|
||||
/>
|
||||
<path
|
||||
d="m 51.064583,81.492642 1e-6,-1.587499 1.322916,0.79375 v -10e-7 z"
|
||||
id="PumpTriangle"
|
||||
/>
|
||||
<path
|
||||
style={stylePump2}
|
||||
d="m 48.948828,78.052995 v 5.292056 h 0.13086 l 5.158984,-2.6e-4 v -5.292057 z m 0.263672,0.263672 4.7625,-2.61e-4 v 4.762761 l -4.7625,2.6e-4 z"
|
||||
id="PumpSquare"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
383
src/components/Sludge.jsx
Normal file
@ -0,0 +1,383 @@
|
||||
let date = new Date().toLocaleString()
|
||||
|
||||
export function Sludge() {
|
||||
return (<>
|
||||
<table cellspacing="0" border="0">
|
||||
<colGroup span="22" width="85"></colGroup>
|
||||
<tr>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" height="130" align="center" valign="middle" bgcolor="#FFFF99"><b><font face="Tahoma"
|
||||
size="2">N пробы</font></b>
|
||||
</td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#FFFF99"><b><font face="Tahoma" size="2">Глубина
|
||||
отбора пробы</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} colSpan="9" align="center" valign="middle" bgcolor="#FFFF99"><b><font face="Tahoma"
|
||||
size="2">Литология</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#FFFF99"><b><font face="Tahoma" size="2">Краткое
|
||||
описание</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#AFABAB"><b><font face="Tahoma" size="2">ЛБА
|
||||
бурового раствора </font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px double #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#FFCC99"><b><font face="Tahoma" size="2">ЛБА
|
||||
(шлама)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderBottom: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} colSpan="6" align="center" valign="bottom" bgcolor="#FFFF99" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">Газопоказания</font></b>
|
||||
</td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "2px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#FFFF99" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">Мех.
|
||||
скорость</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "2px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="3" align="center" valign="middle" bgcolor="#FFCC99" sdnum="1049;0;0,00"><b><font
|
||||
face="Tahoma" size="2">Предварительное заключение о насыщении по ГК</font></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Песчаник
|
||||
(%) </font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Алевролит
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Аргиллит
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Аргиллит
|
||||
бит. (%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Уголь
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Песок
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Глина
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Известняк
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderTop: "2px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "2px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF"><b><font face="Tahoma" size="2">Цемент
|
||||
(%)</font></b></td>
|
||||
<td style={{
|
||||
borderLeft: "2px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">Сумма
|
||||
УВ мах. (абс%) </font></b></td>
|
||||
<td style={{
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">С1
|
||||
метан (отн%)</font></b></td>
|
||||
<td style={{
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">С2 этан
|
||||
(отн%)</font></b></td>
|
||||
<td style={{borderRight: "1px solid #000000", fontSize: "14", fontFamily: "Tahoma, sans-serif"}} rowSpan="2"
|
||||
align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma" size="2">С3
|
||||
пропан (отн%)</font></b></td>
|
||||
<td style={{
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} rowSpan="2" align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma"
|
||||
size="2">С4
|
||||
бутан (отн%)</font></b></td>
|
||||
<td style={{borderLeft: "1px solid #000000", fontSize: "14", fontFamily: "Tahoma, sans-serif"}} rowSpan="2"
|
||||
align="center" valign="middle" bgcolor="#CCCCFF" sdnum="1049;0;0,000"><b><font face="Tahoma" size="2">С5
|
||||
пентан (отн%)</font></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} height="40" align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
<td style={{
|
||||
borderTop: "1px solid #000000",
|
||||
borderBottom: "1px solid #000000",
|
||||
borderLeft: "1px solid #000000",
|
||||
borderRight: "1px solid #000000",
|
||||
fontSize: "14",
|
||||
fontFamily: "Tahoma, sans-serif"
|
||||
}} align="left" valign="bottom"><font size="2" color="#000000"><br/></font></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div> </div>
|
||||
<p style={{textAlign: "right"}}><b>{date}</b></p>
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
import {Layout, Menu} from "antd";
|
||||
import {FolderOutlined, FundViewOutlined} from "@ant-design/icons";
|
||||
import {Link, Redirect, Route, Switch, useParams} from "react-router-dom";
|
||||
import Files from "../pages/Files";
|
||||
import Archive from "../pages/Archive";
|
||||
import Messages from "../pages/Messages";
|
||||
import Report from "../pages/Report";
|
||||
import Analysis from "../pages/Analysis";
|
||||
import TelemetryView from "../pages/TelemetryView";
|
||||
|
||||
const { Content } = Layout
|
||||
|
||||
export default function Well() {
|
||||
let { id } = useParams()
|
||||
|
||||
return (<>
|
||||
<Layout>
|
||||
<Menu
|
||||
mode="horizontal"
|
||||
selectable={true}
|
||||
className="well_menu"
|
||||
>
|
||||
<Menu.Item key="1" icon={<FundViewOutlined/>}>
|
||||
<Link to='telemetry'>Мониторинг</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2" icon={<FolderOutlined/>}>
|
||||
<Link to='message'>Сообщения</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="3" icon={<FolderOutlined/>}>
|
||||
<Link to='report'>Рапорт</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="4" icon={<FolderOutlined/>}>
|
||||
<Link to='analysis'>Анализ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="5" icon={<FolderOutlined/>}>
|
||||
<Link to='file'>Файлы</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="6" icon={<FolderOutlined/>}>
|
||||
<Link to='archive'>Архив</Link>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
|
||||
<Layout>
|
||||
<Content className="site-layout-background">
|
||||
<Switch>
|
||||
<Route path="/well/:id/file">
|
||||
<Files/>
|
||||
</Route>
|
||||
<Route path="/well/:id/archive">
|
||||
<Archive/>
|
||||
</Route>
|
||||
<Route path="/well/:id/message">
|
||||
<Messages/>
|
||||
</Route>
|
||||
<Route path="/well/:id/report">
|
||||
<Report/>
|
||||
</Route>
|
||||
<Route path="/well/:id/analysis">
|
||||
<Analysis/>
|
||||
</Route>
|
||||
<Route path="/well/:id/telemetry">
|
||||
<TelemetryView/>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Redirect to={{pathname: `/well/${id}/telemetry`}}/>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</>)
|
||||
}
|
@ -1,71 +1,55 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { WellService } from '../services/api'
|
||||
import Loader from '../components/Loader'
|
||||
import { useRouteMatch } from 'react-router-dom'
|
||||
import { DepositService } from '../services/api'
|
||||
import LoaderPortal from './LoaderPortal'
|
||||
import { TreeSelect } from 'antd'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import notify from './notify'
|
||||
|
||||
const groupBy = (table, ...keys) => {
|
||||
let key = keys[0]
|
||||
|
||||
let groups = table.reduce((rv, item) => {
|
||||
let keyValue = item[key]
|
||||
let group = rv.find(o => o.title === keyValue)
|
||||
if (!group) {
|
||||
group = {
|
||||
title: keyValue,
|
||||
value: keys.length === 1 ? `${item['id']}` : `${key} ${keyValue} ${item['id']}`,
|
||||
selectable: keys.length === 1,
|
||||
children: []
|
||||
}
|
||||
rv.push(group)
|
||||
}
|
||||
if (keys.length > 1)
|
||||
group.children.push(item);
|
||||
return rv;
|
||||
}, []);
|
||||
|
||||
if (keys.length > 1) {
|
||||
for (let group of groups) {
|
||||
group.children = groupBy(group.children, ...keys.slice(1))
|
||||
}
|
||||
}
|
||||
|
||||
return groups
|
||||
};
|
||||
|
||||
export default function WellTreeSelector(props) {
|
||||
// const [wells, setWells] = useState([])
|
||||
export default function WellTreeSelector() {
|
||||
const [wellsTree, setWellsTree] = useState([])
|
||||
const [loader, setLoader] = useState(false)
|
||||
const [showLoader, setShowLoader] = useState(false)
|
||||
const history = useHistory()
|
||||
let { id } = useParams();
|
||||
const routeMatch = useRouteMatch('/:route/:id')
|
||||
|
||||
let updateWellsList = async () => {
|
||||
setLoader(true)
|
||||
const updateWellsList = async () => {
|
||||
setShowLoader(true)
|
||||
try {
|
||||
let newWells = (await WellService.getWells()).map(w => { return { key: w.id, ...w } })
|
||||
let wellsTree = groupBy(newWells, 'deposit', 'cluster', 'caption')
|
||||
const deposits = await DepositService.getDeposits()
|
||||
const wellsTree = deposits.map(deposit =>({
|
||||
title: deposit.caption,
|
||||
key: `/deposit/${deposit.id}`,
|
||||
value: `/deposit/${deposit.id}`,
|
||||
children: deposit.clusters.map(cluster => ({
|
||||
title: cluster.caption,
|
||||
key: `/cluster/${cluster.id}`,
|
||||
value: `/cluster/${cluster.id}`,
|
||||
children: cluster.wells.map(well => ({
|
||||
title: well.caption,
|
||||
key: `/well/${well.id}`,
|
||||
value: `/well/${well.id}`,
|
||||
})),
|
||||
})),
|
||||
}))
|
||||
setWellsTree(wellsTree)
|
||||
}
|
||||
catch (e) {
|
||||
notify('Не удалось загрузить список скважин', 'error')
|
||||
console.error(`${e.message}`);
|
||||
console.error(`${e.message}`)
|
||||
}
|
||||
setLoader(false)
|
||||
setShowLoader(false)
|
||||
}
|
||||
|
||||
useEffect(() => { updateWellsList() }, [])
|
||||
|
||||
const onSelect = (value) => {
|
||||
const onSelect = (value, node) => {
|
||||
if (value)
|
||||
history.push(`/well/${value}/`);
|
||||
history.push(value);
|
||||
console.log(value)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<LoaderPortal show={showLoader}>
|
||||
<TreeSelect
|
||||
className='header-tree-select'
|
||||
bordered={false}
|
||||
@ -74,9 +58,8 @@ export default function WellTreeSelector(props) {
|
||||
treeData={wellsTree}
|
||||
treeDefaultExpandAll
|
||||
onSelect={onSelect}
|
||||
value = {id}
|
||||
value = {routeMatch?.url}
|
||||
/>
|
||||
{loader && <Loader />}
|
||||
</>
|
||||
</LoaderPortal>
|
||||
)
|
||||
}
|
BIN
src/images/DempherOff.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
src/images/DempherOn.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/images/SpinDisabled.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/images/SpinEnabled.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/images/las.png
Normal file
After Width: | Height: | Size: 965 B |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
BIN
src/images/pdf.png
Normal file
After Width: | Height: | Size: 35 KiB |
12
src/images/pointer.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg width="48" height="48" version="1.1" viewBox="0 0 7.9 7.9" xmlns="http://www.w3.org/2000/svg" xmlns:osb="http://www.openswatchbook.org/uri/2009/osb">
|
||||
<g stroke="#000">
|
||||
<path d="m3.1 1.6 1.9 1.5-2.3 1.1 2.9 2-0.78-4.6h-1.7l-0.78 4.6 2.9-2-2.3-1.1 1.9-1.5" fill="none" stroke-linecap="round" stroke-linejoin="bevel" stroke-width=".17"/>
|
||||
<rect x="2.8" y=".98" width="2.3" height=".45" stroke-width=".084"/>
|
||||
<rect x="3.4" y=".31" width="1.2" height=".45" stroke-width=".084"/>
|
||||
<g fill="none" stroke-width=".084">
|
||||
<rect x="3.9" y="1.6" width=".11" height="6" stroke-linejoin="round"/>
|
||||
<path d="m1.2 6.2 2.1 8e-7v1.5"/>
|
||||
<path d="m4.5 7.7v-1.5l1.9-8e-7"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 691 B |
BIN
src/images/xlsx.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
143
src/pages/Cluster.jsx
Normal file
@ -0,0 +1,143 @@
|
||||
import {useParams} from "react-router-dom";
|
||||
import {Link} from "react-router-dom";
|
||||
import LoaderPortal from '../components/LoaderPortal'
|
||||
import { useState, useEffect } from "react";
|
||||
import {ClusterService} from '../services/api'
|
||||
import notify from '../components/notify'
|
||||
import {Table, Tag, Button} from 'antd';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'скв №',
|
||||
key: 'caption',
|
||||
dataIndex: 'caption',
|
||||
render: (_, item) => <Link to={`/well/${item.id}`}>{item.caption}</Link>
|
||||
},
|
||||
{
|
||||
title: 'Тип скв.',
|
||||
key: 'wellType',
|
||||
dataIndex: 'wellType',
|
||||
},
|
||||
{
|
||||
title: 'Фактические сроки бурения',
|
||||
children: [
|
||||
{
|
||||
title: 'начало',
|
||||
key: 'factStart',
|
||||
dataIndex: 'factStart',
|
||||
},
|
||||
{
|
||||
title: 'окончание',
|
||||
key: 'factEnd',
|
||||
dataIndex: 'factEnd',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Продолжительность бурения',
|
||||
children: [
|
||||
{
|
||||
title: 'план',
|
||||
key: 'periodPlan',
|
||||
dataIndex: 'periodPlan',
|
||||
},
|
||||
{
|
||||
title: 'факт',
|
||||
key: 'periodFact',
|
||||
dataIndex: 'periodFact',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'МСП за скв',
|
||||
children: [
|
||||
{
|
||||
title: 'план',
|
||||
key: 'rateOfPenetrationPlan',
|
||||
dataIndex: 'rateOfPenetrationPlan',
|
||||
},
|
||||
{
|
||||
title: 'факт',
|
||||
key: 'rateOfPenetrationFact',
|
||||
dataIndex: 'rateOfPenetrationFact',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Рейсовая скорость за скв',
|
||||
children: [
|
||||
{
|
||||
title: 'план',
|
||||
key: 'routeSpeedPlan',
|
||||
dataIndex: 'routeSpeedPlan',
|
||||
},
|
||||
{
|
||||
title: 'факт',
|
||||
key: 'routeSpeedFact',
|
||||
dataIndex: 'routeSpeedFact',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Секции',
|
||||
key: 'sections',
|
||||
dataIndex: 'sections',
|
||||
render: (item) => (<span>таблица по секциям</span>)
|
||||
},
|
||||
{
|
||||
title: 'График глубина-день',
|
||||
render: _ => (<Button>Открыть</Button>)
|
||||
},
|
||||
{
|
||||
title: 'Таблица по операциям',
|
||||
render: _ => (<Button>Открыть</Button>)
|
||||
},
|
||||
{
|
||||
title: 'Подрядчики',
|
||||
key: 'companies',
|
||||
dataIndex: 'companies',
|
||||
render: (item) => item.map(company => <Tag color="blue">{company.caption}</Tag>)
|
||||
},
|
||||
];
|
||||
|
||||
export default function Cluster() {
|
||||
let { id } = useParams()
|
||||
const [clusterTitle, setClusterTitle] = useState("")
|
||||
const [wellsStat, setWellsStat] = useState(null)
|
||||
const [showLoader, setShowLoader] = useState(false)
|
||||
|
||||
useEffect(()=>{
|
||||
const updateWellsStat = async() => {
|
||||
setShowLoader(true)
|
||||
try{
|
||||
const msInDay = 1000*60*60*24
|
||||
const data = await ClusterService.getStat(id)
|
||||
const wellsStat = data.wellsStat.map(w=>({...w,
|
||||
periodPlan: (new Date(w.planEnd) - new Date(w.planStart))/msInDay,
|
||||
periodFact: (new Date(w.factEnd) - new Date(w.factStart))/msInDay,
|
||||
}))
|
||||
setWellsStat(wellsStat)
|
||||
setClusterTitle(data.caption)
|
||||
}
|
||||
catch(ex) {
|
||||
notify(`Не удалось загрузить статистику по скважинам куста "${id}"`, 'error')
|
||||
console.log(ex)
|
||||
}
|
||||
setShowLoader(false)
|
||||
}
|
||||
updateWellsStat()
|
||||
},[id])
|
||||
|
||||
return(
|
||||
<LoaderPortal show={showLoader}>
|
||||
<h3>{clusterTitle}</h3>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={wellsStat}
|
||||
size={'small'}
|
||||
bordered
|
||||
pagination={false}
|
||||
rowKey={(record) => record.id}
|
||||
/>
|
||||
</LoaderPortal>)
|
||||
}
|
74
src/pages/Deposit.jsx
Normal file
@ -0,0 +1,74 @@
|
||||
import { Map, Overlay } from "pigeon-maps"
|
||||
import pointer from '../images/pointer.svg'
|
||||
import {Link} from "react-router-dom";
|
||||
import LoaderPortal from '../components/LoaderPortal'
|
||||
import { useState, useEffect } from "react";
|
||||
import {ClusterService} from '../services/api'
|
||||
import notify from '../components/notify'
|
||||
|
||||
const calcViewParams = (clusters) => {
|
||||
if ((!clusters) || clusters.length === 0)
|
||||
return {center:[60.81226, 70.0562], zoom: 5}
|
||||
|
||||
const center = clusters.reduce((sum, cluster) => {
|
||||
sum[0] += (cluster.latitude / clusters.length)
|
||||
sum[1] += (cluster.longitude / clusters.length)
|
||||
return sum
|
||||
}, [0, 0])
|
||||
|
||||
const maxDeg = clusters.reduce((max, cluster) => {
|
||||
const dLatitude = Math.abs(center[0] - cluster.latitude)
|
||||
const dLongitude = Math.abs(center[1] - cluster.longitude)
|
||||
const d = dLatitude > dLongitude ? dLatitude : dLongitude
|
||||
return d > max ? d : max
|
||||
}, 0)
|
||||
|
||||
return {center, zoom: maxDeg*25}
|
||||
}
|
||||
|
||||
export default function Deposit() {
|
||||
const [clustersData, setClustersData] = useState([])
|
||||
const [showLoader, setShowLoader] = useState(false)
|
||||
|
||||
useEffect(()=>{
|
||||
const updateClusters = async()=>{
|
||||
setShowLoader(true)
|
||||
try{
|
||||
const data = await ClusterService.getClusters()
|
||||
setClustersData(data)
|
||||
}
|
||||
catch(ex) {
|
||||
notify(`Не удалось загрузить список кустов`, 'error')
|
||||
console.log(ex)
|
||||
}
|
||||
setShowLoader(false)
|
||||
}
|
||||
updateClusters()
|
||||
}, [])
|
||||
|
||||
const viewParams = calcViewParams(clustersData)
|
||||
|
||||
const markers = clustersData.map(cluster =>
|
||||
<Overlay
|
||||
width={32}
|
||||
anchor={[cluster.latitude, cluster.longitude]}
|
||||
key={`${cluster.latitude} ${cluster.longitude}`}
|
||||
>
|
||||
<Link to={`/cluster/${cluster.id}`}>
|
||||
<img width={40} src={pointer} alt="+"/>
|
||||
<span>{cluster.caption}</span>
|
||||
</Link>
|
||||
|
||||
</Overlay >)
|
||||
|
||||
return (
|
||||
<LoaderPortal show={showLoader}>
|
||||
<Map
|
||||
height='100vh'
|
||||
center={viewParams.center}
|
||||
zoom={viewParams.zoom}>
|
||||
{markers}
|
||||
</Map>
|
||||
</LoaderPortal>
|
||||
);
|
||||
}
|
8
src/pages/FluidService.jsx
Normal file
@ -0,0 +1,8 @@
|
||||
import Documents from "../components/Documents"
|
||||
|
||||
export default function FluidService({selectedFileCategory}) {
|
||||
|
||||
return(
|
||||
<Documents selectedFileCategory={selectedFileCategory} />
|
||||
)
|
||||
}
|
94
src/pages/LastData.jsx
Normal file
@ -0,0 +1,94 @@
|
||||
import {Button, Modal, Checkbox } from "antd";
|
||||
import {CementFluid} from "../components/CementFluid";
|
||||
import React, {useState} from "react";
|
||||
import {Sludge} from "../components/Sludge";
|
||||
import {NnbTable} from "../components/NnbTable"
|
||||
import Disposition from "../components/Disposition";
|
||||
import MenuDocuments from "../components/MenuDocuments";
|
||||
|
||||
|
||||
export default function LastData() {
|
||||
const [tableVisible, setTableVisible] = useState(false)
|
||||
const [tableSludgeVisible, setTableSludgeVisible] = useState(false)
|
||||
const [tableNNBVisible, setTableNNBVisible] = useState(false)
|
||||
const [dispositionVisible, setDispositionVisible] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<MenuDocuments/>
|
||||
</div>
|
||||
<div> </div>
|
||||
<Button type="primary" onClick={() => setTableVisible(true)}>
|
||||
Последний замер бурового раствора
|
||||
</Button>
|
||||
<Modal
|
||||
title='Последние показатели бурового раствора'
|
||||
centered
|
||||
visible={tableVisible}
|
||||
onOk={() => setTableVisible(false)}
|
||||
onCancel={() => setTableVisible(false)}
|
||||
width={1800}
|
||||
okText='Ок'
|
||||
cancelText='Отмена'
|
||||
>
|
||||
<CementFluid/>
|
||||
</Modal>
|
||||
<Button type="primary" onClick={() => setTableSludgeVisible(true)} style={{marginLeft: "5px"}}>
|
||||
Шламограмма
|
||||
</Button>
|
||||
<Modal
|
||||
title='Шламограмма'
|
||||
centered
|
||||
visible={tableSludgeVisible}
|
||||
onOk={() => setTableSludgeVisible(false)}
|
||||
onCancel={() => setTableSludgeVisible(false)}
|
||||
width={1600}
|
||||
okText='Ок'
|
||||
cancelText='Отмена'
|
||||
>
|
||||
<Sludge/>
|
||||
</Modal>
|
||||
<Button type="primary" onClick={() => setTableNNBVisible(true)} style={{marginLeft: "5px"}}>
|
||||
ННБ
|
||||
</Button>
|
||||
<Modal
|
||||
title='ННБ'
|
||||
centered
|
||||
visible={tableNNBVisible}
|
||||
onOk={() => setTableNNBVisible(false)}
|
||||
onCancel={() => setTableNNBVisible(false)}
|
||||
width={1400}
|
||||
okText='Ок'
|
||||
cancelText='Отмена'
|
||||
>
|
||||
<NnbTable/>
|
||||
</Modal>
|
||||
<Button type="primary" onClick={() => setDispositionVisible(true)} style={{marginLeft: "5px"}}>
|
||||
Распоряжение
|
||||
</Button>
|
||||
<Modal
|
||||
title='Распоряжение'
|
||||
centered
|
||||
visible={dispositionVisible}
|
||||
onOk={() => setDispositionVisible(false)}
|
||||
onCancel={() => setDispositionVisible(false)}
|
||||
width={850}
|
||||
okText='Ок'
|
||||
cancelText='Отмена'
|
||||
footer={[
|
||||
<Checkbox style={{marginRight: '10px'}}>Принять распоряжение</Checkbox>,
|
||||
<Button key="submit" type="secondary"
|
||||
onClick={() => setDispositionVisible(false)}>
|
||||
Отмена
|
||||
</Button>,
|
||||
<Button key="submit" type="primary"
|
||||
onClick={() => setDispositionVisible(false)}>
|
||||
Ок
|
||||
</Button>
|
||||
]}
|
||||
>
|
||||
<Disposition/>
|
||||
</Modal>
|
||||
</>)
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import {Layout} from 'antd'
|
||||
import PageHeader from './Header'
|
||||
|
||||
const {Content} = Layout
|
||||
|
||||
export default function LayoutPortal({title, children}) {
|
||||
return (
|
||||
<Content>
|
||||
<PageHeader title={title}/>
|
||||
<Layout>
|
||||
<Content className="site-layout-background sheet">
|
||||
{children}
|
||||
</Content>
|
||||
</Layout>
|
||||
</Content>)
|
||||
}
|
@ -17,6 +17,7 @@ const openNotificationError = (message, title) => {
|
||||
|
||||
const setUser = (user) =>{
|
||||
OpenAPI.TOKEN = user.token
|
||||
localStorage['userId'] = user.id
|
||||
localStorage['token'] = user.token
|
||||
localStorage['login'] = user.login
|
||||
}
|
||||
|
@ -1,25 +1,31 @@
|
||||
import Wells from './Wells'
|
||||
import Well from "../components/Well";
|
||||
import LayoutPortal from './LayoutPortal'
|
||||
import Deposit from './Deposit'
|
||||
import Cluster from './Cluster'
|
||||
import Well from "./Well";
|
||||
import LayoutPortal from '../components/LayoutPortal'
|
||||
import {Redirect, Route, Switch} from "react-router-dom";
|
||||
|
||||
export default function Main() {
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path="/well/:id/">
|
||||
<LayoutPortal>
|
||||
<Well/>
|
||||
</LayoutPortal>
|
||||
</Route>
|
||||
<Route path="/well">
|
||||
<LayoutPortal>
|
||||
<Wells/>
|
||||
</LayoutPortal>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Redirect to={{pathname: `/well`}}/>
|
||||
</Route>
|
||||
</Switch>
|
||||
return (
|
||||
<Switch>
|
||||
<Route path="/well/:id/">
|
||||
<LayoutPortal>
|
||||
<Well/>
|
||||
</LayoutPortal>
|
||||
</Route>
|
||||
<Route path="/deposit">
|
||||
<LayoutPortal noSheet>
|
||||
<Deposit/>
|
||||
</LayoutPortal>
|
||||
</Route>
|
||||
<Route path="/cluster/:id/">
|
||||
<LayoutPortal>
|
||||
<Cluster/>
|
||||
</LayoutPortal>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Redirect to={{pathname: `/deposit`}}/>
|
||||
</Route>
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ export default function Messages() {
|
||||
return (
|
||||
<>
|
||||
<div className='filter-group'>
|
||||
<h3 className='filter-group__heading'>Фильтр сообщений</h3>
|
||||
<h3 className='filter-group-heading'>Фильтр сообщений</h3>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
|
@ -78,7 +78,7 @@ export default function Report(props) {
|
||||
title: 'Название отчета',
|
||||
dataIndex: 'reportName',
|
||||
key: 'reportName',
|
||||
render: name => <a onClick={event => getReportFile(event, name)} download={name}>{name}</a>
|
||||
render: name => <button onClick={event => getReportFile(event, name)} download={name}>{name}</button>
|
||||
},
|
||||
];
|
||||
|
||||
@ -91,10 +91,10 @@ export default function Report(props) {
|
||||
<br />
|
||||
<span> { progressData.operation } </span>
|
||||
<br />
|
||||
<a onClick={event => {getReportFile(event, progressData.reportName)}}
|
||||
<button onClick={event => {getReportFile(event, progressData.reportName)}}
|
||||
download={progressData.reportName}>
|
||||
{ progressData.reportName }
|
||||
</a>
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -183,7 +183,7 @@ export default function Report(props) {
|
||||
}
|
||||
|
||||
getRepostSizeAsync()
|
||||
},[rangeDate, step, format])
|
||||
},[rangeDate, step, format, wellId])
|
||||
|
||||
useEffect(()=>{
|
||||
async function getSuitableReportsAsync() {
|
||||
@ -215,7 +215,7 @@ export default function Report(props) {
|
||||
}
|
||||
|
||||
getSuitableReportsAsync()
|
||||
},[rangeDate, step, format])
|
||||
},[rangeDate, step, format, wellId])
|
||||
|
||||
useEffect(()=>{
|
||||
async function getDatesRange() {
|
||||
@ -225,7 +225,7 @@ export default function Report(props) {
|
||||
}
|
||||
|
||||
getDatesRange()
|
||||
},[])
|
||||
},[wellId])
|
||||
|
||||
return (<>
|
||||
<div className="w-100 mt-20px">
|
||||
|
@ -12,7 +12,7 @@ import moment from 'moment'
|
||||
import {Subscribe} from '../services/signalr'
|
||||
import {DataService, MessageService} from '../services/api'
|
||||
import '../styles/message.css'
|
||||
import notify from "../components/notify";
|
||||
import notify from "../components/notify"
|
||||
|
||||
const {Option} = Select
|
||||
|
||||
@ -60,7 +60,7 @@ const axialLoadGroup = {
|
||||
}
|
||||
|
||||
const hookWeightGroup = {
|
||||
label: "Ввес на крюке",
|
||||
label: "Вес на крюке",
|
||||
yDisplay: false,
|
||||
linePv: {label: "hookWeight", units: 'т', xAccessorName: "hookWeight", yAccessorName: "date", color: '#0aa'},
|
||||
lineIdle: {
|
||||
@ -114,7 +114,7 @@ const rotorTorqueGroup = {
|
||||
|
||||
const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup]
|
||||
|
||||
export const Column = ({lineGroup, data, interval}) => {
|
||||
export const Column = ({lineGroup, data, interval, showBorder}) => {
|
||||
let lines = [lineGroup.linePv]
|
||||
|
||||
if (lineGroup.lineSp)
|
||||
@ -123,6 +123,12 @@ export const Column = ({lineGroup, data, interval}) => {
|
||||
if (lineGroup.lineOther)
|
||||
lines.push(lineGroup.lineOther)
|
||||
|
||||
if (lineGroup.lineAvg)
|
||||
lines.push(lineGroup.lineAvg)
|
||||
|
||||
if (lineGroup.lineMax)
|
||||
lines.push(lineGroup.lineMax)
|
||||
|
||||
let dataLast = null
|
||||
let pv = null
|
||||
if (data?.length > 0) {
|
||||
@ -133,10 +139,12 @@ export const Column = ({lineGroup, data, interval}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Display
|
||||
label={lineGroup.label}
|
||||
value={pv}
|
||||
suffix={lineGroup.linePv?.units} isArrowVisible={true}/>
|
||||
<div style={{boxShadow: showBorder ? "inset 0px 0px 0px 3px black" : ""}}>
|
||||
<Display
|
||||
label={lineGroup.label}
|
||||
value={pv}
|
||||
suffix={lineGroup.linePv?.units} isArrowVisible={false}/>
|
||||
</div>
|
||||
<ChartTimeOnline
|
||||
data={data}
|
||||
yDisplay={lineGroup.yDisplay}
|
||||
@ -197,10 +205,12 @@ const timePeriodCollection = [
|
||||
export default function TelemetryView(props) {
|
||||
let {id} = useParams()
|
||||
const [saubData, setSaubData] = useState([])
|
||||
const [chartInterval, setChartInterval] = useState(600)
|
||||
const [chartInterval, setChartInterval] = useState(defaultInterval)
|
||||
const [messages, setMessages] = useState([])
|
||||
|
||||
const [loader, setLoader] = useState(false) // , setLoader
|
||||
const [loader, setLoader] = useState(false)
|
||||
|
||||
const periods = intervalSteps.map((line) => <Option key={line.value} value={line.value}>{line.label}</Option>)
|
||||
|
||||
const children = timePeriodCollection.map((line) => <Option key={line.value}>{line.label}</Option>)
|
||||
|
||||
@ -270,14 +280,14 @@ export default function TelemetryView(props) {
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={2}>
|
||||
<Col span={3}>
|
||||
<CustomColumn data={saubData}/>
|
||||
</Col>
|
||||
<Col span={24 - 2}>
|
||||
<Col span={24 - 3}>
|
||||
<Row>
|
||||
{paramsGroups.map(group =>
|
||||
{paramsGroups.map((group, index) =>
|
||||
<Col span={colSpan} className='border_small' key={group.label}>
|
||||
<Column data={saubData} lineGroup={group} interval={chartInterval}/>
|
||||
<Column data={saubData} lineGroup={group} interval={chartInterval} showBorder = {saubData[saubData.length - 1]?.drillingBy === index}/>
|
||||
</Col>)}
|
||||
</Row>
|
||||
</Col>
|
||||
|
141
src/pages/Well.jsx
Normal file
@ -0,0 +1,141 @@
|
||||
import {Layout, Menu} from "antd";
|
||||
import {FolderOutlined, FundViewOutlined} from "@ant-design/icons";
|
||||
import {Link, Redirect, Route, Switch, useParams} from "react-router-dom";
|
||||
import Files from "../pages/Files";
|
||||
import Archive from "../pages/Archive";
|
||||
import Messages from "../pages/Messages";
|
||||
import Report from "../pages/Report";
|
||||
import Analysis from "../pages/Analysis";
|
||||
import WellAnalysis from "../pages/WellAnalysis";
|
||||
import Documents from "../components/Documents";
|
||||
import LastData from '../pages/LastData'
|
||||
import TelemetryView from "../pages/TelemetryView";
|
||||
|
||||
const { Content } = Layout
|
||||
|
||||
export default function Well() {
|
||||
let { id } = useParams()
|
||||
|
||||
const {SubMenu} = Menu
|
||||
|
||||
return (<>
|
||||
<Layout>
|
||||
<Menu
|
||||
mode="horizontal"
|
||||
selectable={true}
|
||||
className="well_menu"
|
||||
>
|
||||
<Menu.Item key="1" icon={<FundViewOutlined/>}>
|
||||
<Link to='telemetry'>Мониторинг</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2" icon={<FolderOutlined/>}>
|
||||
<Link to='message'>Сообщения</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="3" icon={<FolderOutlined/>}>
|
||||
<Link to='report'>Рапорт</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="4" icon={<FolderOutlined/>}>
|
||||
<Link to='analysis'>Анализ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="5" icon={<FolderOutlined/>}>
|
||||
<Link to='wellAnalysis'>Операции по скважине</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="6" icon={<FolderOutlined/>}>
|
||||
<Link to='file'>Файлы</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="7" icon={<FolderOutlined/>}>
|
||||
<Link to='archive'>Архив</Link>
|
||||
</Menu.Item>
|
||||
<SubMenu
|
||||
key="documentsSub"
|
||||
title={<Link to='fluidService' className="linkDocuments">Документы</Link>}
|
||||
icon={<FolderOutlined/>}
|
||||
selectable={true}
|
||||
>
|
||||
<Menu.Item key="documentsSub1" icon={<FolderOutlined/>}>
|
||||
<Link to='fluidService'>Растворный сервис</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.1" icon={<FolderOutlined/>}>
|
||||
<Link to='cementing'>Цементирование</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.2" icon={<FolderOutlined/>}>
|
||||
<Link to='nnb'>ННБ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.3" icon={<FolderOutlined/>}>
|
||||
<Link to='gti'>ГТИ</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.4" icon={<FolderOutlined/>}>
|
||||
<Link to='documentsForWell'>Документы по скважине</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.5" icon={<FolderOutlined/>}>
|
||||
<Link to='supervisor'>Супервайзер</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.6" icon={<FolderOutlined/>}>
|
||||
<Link to='master'>Мастер</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="documentsSub1.7" icon={<FolderOutlined/>}>
|
||||
<Link to='lastData'>Последние данные</Link>
|
||||
</Menu.Item>
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
|
||||
<Layout>
|
||||
<Content className="site-layout-background">
|
||||
<Switch>
|
||||
<Route path="/well/:id/file">
|
||||
<Files/>
|
||||
</Route>
|
||||
<Route path="/well/:id/archive">
|
||||
<Archive/>
|
||||
</Route>
|
||||
<Route path="/well/:id/message">
|
||||
<Messages/>
|
||||
</Route>
|
||||
<Route path="/well/:id/report">
|
||||
<Report/>
|
||||
</Route>
|
||||
<Route path="/well/:id/analysis">
|
||||
<Analysis/>
|
||||
</Route>
|
||||
<Route path="/well/:id/wellAnalysis">
|
||||
<WellAnalysis/>
|
||||
</Route>
|
||||
<Route path="/well/:id/telemetry">
|
||||
<TelemetryView/>
|
||||
</Route>
|
||||
<Route path="/well/:id/fluidService">
|
||||
<Documents selectedFileCategory={1}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/cementing">
|
||||
<Documents selectedFileCategory={2}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/nnb">
|
||||
<Documents selectedFileCategory={3}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/gti">
|
||||
<Documents selectedFileCategory={4}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/documentsForWell">
|
||||
<Documents selectedFileCategory={5}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/supervisor">
|
||||
<Documents selectedFileCategory={6}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/master">
|
||||
<Documents selectedFileCategory={7}/>
|
||||
</Route>
|
||||
<Route path="/well/:id/lastData">
|
||||
<LastData/>
|
||||
</Route>
|
||||
<Route path="/well/:id/documents">
|
||||
<Documents/>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Redirect to={{pathname: `/well/${id}/telemetry`}}/>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</>)
|
||||
}
|
159
src/pages/WellAnalysis.jsx
Normal file
@ -0,0 +1,159 @@
|
||||
import {Table, Select, DatePicker, ConfigProvider} from 'antd';
|
||||
import {AnalyticsService} from '../services/api'
|
||||
import {useState, useEffect} from 'react'
|
||||
import {useParams} from 'react-router-dom'
|
||||
import notify from '../components/notify'
|
||||
import LoaderPortal from '../components/LoaderPortal'
|
||||
import locale from "antd/lib/locale/ru_RU";
|
||||
import moment from 'moment'
|
||||
import '../styles/message.css'
|
||||
|
||||
const {Option} = Select
|
||||
const pageSize = 26
|
||||
const {RangePicker} = DatePicker;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Название операции',
|
||||
key: 'name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Дата начала операции',
|
||||
key: 'beginDate',
|
||||
dataIndex: 'beginDate',
|
||||
render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss')
|
||||
},
|
||||
{
|
||||
title: 'Дата окончания операции',
|
||||
key: 'endDate',
|
||||
dataIndex: 'endDate',
|
||||
render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss')
|
||||
},
|
||||
{
|
||||
title: 'Глубина скважины в начале операции',
|
||||
key: 'beginWellDepth',
|
||||
dataIndex: 'startWellDepth',
|
||||
},
|
||||
{
|
||||
title: 'Глубина скважины в конце операции',
|
||||
key: 'endWellDepth',
|
||||
dataIndex: 'endWellDepth',
|
||||
}
|
||||
];
|
||||
|
||||
const filterOptions = [
|
||||
{label: 'Невозможно определить операцию', value: 1},
|
||||
{label: 'Роторное бурение', value: 2},
|
||||
{label: 'Слайдирование', value: 3},
|
||||
{label: 'Подъем с проработкой', value: 4},
|
||||
{label: 'Спуск с проработкой', value: 5},
|
||||
{label: 'Подъем с промывкой', value: 6},
|
||||
{label: 'Спуск с промывкой', value: 7},
|
||||
{label: 'Спуск в скважину', value: 8},
|
||||
{label: 'Спуск с вращением', value: 9},
|
||||
{label: 'Подъем из скважины', value: 10},
|
||||
{label: 'Подъем с вращением', value: 11},
|
||||
{label: 'Промывка в покое', value: 12},
|
||||
{label: 'Промывка с вращением', value: 13},
|
||||
{label: 'Удержание в клиньях', value: 14},
|
||||
{label: 'Неподвижное состояние', value: 15},
|
||||
{label: 'Вращение без циркуляции', value: 16},
|
||||
{label: 'На поверхности', value: 17}
|
||||
]
|
||||
|
||||
export default function WellAnalysis() {
|
||||
let {id} = useParams()
|
||||
|
||||
const [page, setPage] = useState(1)
|
||||
const [range, setRange] = useState([])
|
||||
const [categories, setCategories] = useState([])
|
||||
const [pagination, setPagination] = useState(null)
|
||||
const [operations, setOperations] = useState([])
|
||||
|
||||
const [loader, setLoader] = useState(false)
|
||||
|
||||
const children = filterOptions.map((line) => <Option key={line.value}>{line.label}</Option>)
|
||||
|
||||
const onChangeRange = (range) => {
|
||||
setRange(range)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const GetOperations = async () => {
|
||||
setLoader(true)
|
||||
try {
|
||||
let begin = null
|
||||
let end = null
|
||||
if (range?.length > 1) {
|
||||
begin = range[0].toISOString()
|
||||
end = range[1].toISOString()
|
||||
}
|
||||
|
||||
await AnalyticsService.getOperationsByWell(
|
||||
`${id}`,
|
||||
(page-1) * pageSize,
|
||||
pageSize,
|
||||
categories,
|
||||
begin,
|
||||
end).then((paginatedOperations) => {
|
||||
setOperations(paginatedOperations?.items.map(o => {
|
||||
return {
|
||||
key: o.id,
|
||||
begin: o.date,
|
||||
...o
|
||||
}
|
||||
}))
|
||||
|
||||
setPagination({
|
||||
total: paginatedOperations?.count,
|
||||
current: Math.floor(paginatedOperations?.skip / pageSize),
|
||||
})
|
||||
}
|
||||
)
|
||||
} catch (ex) {
|
||||
notify(`Не удалось загрузить операции по скважине "${id}"`, 'error')
|
||||
console.log(ex)
|
||||
}
|
||||
setLoader(false)
|
||||
}
|
||||
GetOperations()
|
||||
}, [id, categories, range, page])
|
||||
|
||||
return(<>
|
||||
<div className='filter-group'>
|
||||
<h3 className='filter-group-heading'>Фильтр операций</h3>
|
||||
<Select
|
||||
mode="multiple"
|
||||
allowClear
|
||||
placeholder="Фильтр операций"
|
||||
className="filter-selector"
|
||||
value={categories}
|
||||
onChange={setCategories}>
|
||||
{children}
|
||||
</Select>
|
||||
<ConfigProvider locale={locale}>
|
||||
<RangePicker
|
||||
showTime
|
||||
placeholder={["Дата начала операции", "Дата окончания операции"]}
|
||||
onChange={onChangeRange}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
<LoaderPortal show={loader}>
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={operations}
|
||||
size={'small'}
|
||||
pagination={{
|
||||
pageSize: pageSize,
|
||||
showSizeChanger: false,
|
||||
total: pagination?.total,
|
||||
current: page,
|
||||
onChange: (page) => setPage(page)
|
||||
}}
|
||||
rowKey={(record) => record.id}
|
||||
/>
|
||||
</LoaderPortal>
|
||||
</>)
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { WellService } from '../services/api'
|
||||
import LoaderPortal from '../components/LoaderPortal'
|
||||
import { Table } from 'antd' // TreeSelect
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import notify from '../components/notify'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Месторождение',
|
||||
dataIndex: 'deposit',
|
||||
key: 'deposit',
|
||||
},
|
||||
{
|
||||
title: 'Куст',
|
||||
dataIndex: 'cluster',
|
||||
key: 'cluster',
|
||||
},
|
||||
{
|
||||
title: 'Скважина',
|
||||
dataIndex: 'caption',
|
||||
key: 'caption',
|
||||
},
|
||||
{
|
||||
title: 'Данные',
|
||||
dataIndex: 'lastData',
|
||||
key: 'lastData',
|
||||
},
|
||||
];
|
||||
|
||||
export default function Wells(props){
|
||||
const [wells, setWells] = useState([])
|
||||
const [loader, setLoader] = useState(false)
|
||||
const history = useHistory()
|
||||
|
||||
const updateWellsList = async () => {
|
||||
setLoader(true)
|
||||
try{
|
||||
let newWells = (await WellService.getWells()).map(w =>{return {key:w.id, ...w}})
|
||||
console.log(newWells)
|
||||
setWells( newWells )
|
||||
}
|
||||
catch(e){
|
||||
notify('Не удалось загрузить список скважин', 'error')
|
||||
console.error(`${e}`);
|
||||
}
|
||||
setLoader(false)
|
||||
}
|
||||
|
||||
useEffect(()=>updateWellsList(), [])
|
||||
|
||||
return(<>
|
||||
<h2>Скважины</h2>
|
||||
<LoaderPortal show={loader}>
|
||||
<Table
|
||||
dataSource={wells}
|
||||
columns={columns}
|
||||
onRow={(record) => {
|
||||
return {
|
||||
onClick: event => {history.push(`/well/${record.id}/`)},
|
||||
};
|
||||
}}/>
|
||||
</LoaderPortal>
|
||||
</>)
|
||||
}
|
@ -5,11 +5,19 @@ export { ApiError } from './core/ApiError';
|
||||
export { OpenAPI } from './core/OpenAPI';
|
||||
|
||||
export type { AuthDto } from './models/AuthDto';
|
||||
export type { ClusterDto } from './models/ClusterDto';
|
||||
export type { ClusterStatDto } from './models/ClusterStatDto';
|
||||
export type { CompanyDto } from './models/CompanyDto';
|
||||
export type { DataSaubBaseDto } from './models/DataSaubBaseDto';
|
||||
export type { DatesRangeDto } from './models/DatesRangeDto';
|
||||
export type { DepositDto } from './models/DepositDto';
|
||||
export type { EventDto } from './models/EventDto';
|
||||
export type { FilePropertiesDto } from './models/FilePropertiesDto';
|
||||
export type { FilePropertiesDtoPaginationContainer } from './models/FilePropertiesDtoPaginationContainer';
|
||||
export type { MessageDto } from './models/MessageDto';
|
||||
export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer';
|
||||
export type { OperationDto } from './models/OperationDto';
|
||||
export type { OperationDtoPaginationContainer } from './models/OperationDtoPaginationContainer';
|
||||
export type { OperationDurationDto } from './models/OperationDurationDto';
|
||||
export type { TelemetryInfoDto } from './models/TelemetryInfoDto';
|
||||
export type { TelemetryMessageDto } from './models/TelemetryMessageDto';
|
||||
@ -18,10 +26,15 @@ export type { UserTokenDto } from './models/UserTokenDto';
|
||||
export type { WellDepthToDayDto } from './models/WellDepthToDayDto';
|
||||
export type { WellDepthToIntervalDto } from './models/WellDepthToIntervalDto';
|
||||
export type { WellDto } from './models/WellDto';
|
||||
export type { WellSectionDto } from './models/WellSectionDto';
|
||||
export type { WellStatDto } from './models/WellStatDto';
|
||||
|
||||
export { AnalyticsService } from './services/AnalyticsService';
|
||||
export { AuthService } from './services/AuthService';
|
||||
export { ClusterService } from './services/ClusterService';
|
||||
export { DataService } from './services/DataService';
|
||||
export { DepositService } from './services/DepositService';
|
||||
export { FileService } from './services/FileService';
|
||||
export { MessageService } from './services/MessageService';
|
||||
export { ReportService } from './services/ReportService';
|
||||
export { TelemetryService } from './services/TelemetryService';
|
||||
|
14
src/services/api/models/ClusterDto.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { WellDto } from './WellDto';
|
||||
|
||||
export type ClusterDto = {
|
||||
id?: number;
|
||||
caption?: string | null;
|
||||
description?: string | null;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
wells?: Array<WellDto> | null;
|
||||
}
|
16
src/services/api/models/ClusterStatDto.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { WellDto } from './WellDto';
|
||||
import type { WellStatDto } from './WellStatDto';
|
||||
|
||||
export type ClusterStatDto = {
|
||||
id?: number;
|
||||
caption?: string | null;
|
||||
description?: string | null;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
wells?: Array<WellDto> | null;
|
||||
wellsStat?: Array<WellStatDto> | null;
|
||||
}
|
9
src/services/api/models/CompanyDto.ts
Normal file
@ -0,0 +1,9 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type CompanyDto = {
|
||||
id?: number;
|
||||
caption?: string | null;
|
||||
companyType?: string | null;
|
||||
}
|
@ -38,4 +38,6 @@ export type DataSaubBaseDto = {
|
||||
flow?: number | null;
|
||||
flowIdle?: number | null;
|
||||
flowDeltaLimitMax?: number | null;
|
||||
idFeedRegulator?: number | null;
|
||||
mseState?: number | null;
|
||||
}
|
14
src/services/api/models/DepositDto.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { ClusterDto } from './ClusterDto';
|
||||
|
||||
export type DepositDto = {
|
||||
id?: number;
|
||||
caption?: string | null;
|
||||
description?: string | null;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
clusters?: Array<ClusterDto> | null;
|
||||
}
|
11
src/services/api/models/FilePropertiesDto.ts
Normal file
@ -0,0 +1,11 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type FilePropertiesDto = {
|
||||
id?: number;
|
||||
name?: string | null;
|
||||
idCategory?: number;
|
||||
uploadDate?: string;
|
||||
userName?: string | null;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { FilePropertiesDto } from './FilePropertiesDto';
|
||||
|
||||
export type FilePropertiesDtoPaginationContainer = {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
count?: number;
|
||||
items?: Array<FilePropertiesDto> | null;
|
||||
}
|
12
src/services/api/models/OperationDto.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type OperationDto = {
|
||||
id?: number;
|
||||
name?: string | null;
|
||||
beginDate?: string;
|
||||
endDate?: string;
|
||||
startWellDepth?: number;
|
||||
endWellDepth?: number;
|
||||
}
|
12
src/services/api/models/OperationDtoPaginationContainer.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { OperationDto } from './OperationDto';
|
||||
|
||||
export type OperationDtoPaginationContainer = {
|
||||
skip?: number;
|
||||
take?: number;
|
||||
count?: number;
|
||||
items?: Array<OperationDto> | null;
|
||||
}
|
@ -3,6 +3,6 @@
|
||||
/* eslint-disable */
|
||||
|
||||
export type OperationDurationDto = {
|
||||
processName?: string | null;
|
||||
operationName?: string | null;
|
||||
duration?: number;
|
||||
}
|
@ -9,7 +9,7 @@ export type UserTokenDto = {
|
||||
surname?: string | null;
|
||||
patronymic?: string | null;
|
||||
id?: number;
|
||||
customerName?: string | null;
|
||||
companyName?: string | null;
|
||||
roleName?: string | null;
|
||||
token?: string | null;
|
||||
}
|
@ -7,5 +7,7 @@ export type WellDto = {
|
||||
cluster?: string | null;
|
||||
deposit?: string | null;
|
||||
id?: number;
|
||||
lastData?: any;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
wellType?: string | null;
|
||||
}
|
21
src/services/api/models/WellSectionDto.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type WellSectionDto = {
|
||||
sectionType?: string | null;
|
||||
wellDepthPlan?: number;
|
||||
wellDepthFact?: number;
|
||||
buildDaysPlan?: number;
|
||||
buildDaysFact?: number;
|
||||
rateOfPenetrationPlan?: number;
|
||||
rateOfPenetrationFact?: number;
|
||||
routeSpeedPlan?: number;
|
||||
routeSpeedFact?: number;
|
||||
bhaUpSpeedPlan?: number;
|
||||
bhaUpSpeedFact?: number;
|
||||
bhaDownSpeedPlan?: number;
|
||||
bhaDownSpeedFact?: number;
|
||||
casingDownSpeedPlan?: number;
|
||||
casingDownSpeedFact?: number;
|
||||
}
|
27
src/services/api/models/WellStatDto.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
import type { CompanyDto } from './CompanyDto';
|
||||
import type { WellSectionDto } from './WellSectionDto';
|
||||
|
||||
export type WellStatDto = {
|
||||
caption?: string | null;
|
||||
cluster?: string | null;
|
||||
deposit?: string | null;
|
||||
id?: number;
|
||||
latitude?: number | null;
|
||||
longitude?: number | null;
|
||||
wellType?: string | null;
|
||||
planStart?: string | null;
|
||||
planEnd?: string | null;
|
||||
factStart?: string | null;
|
||||
factEnd?: string | null;
|
||||
unProductiveDays?: number | null;
|
||||
rateOfPenetrationPlan?: number | null;
|
||||
rateOfPenetrationFact?: number | null;
|
||||
routeSpeedPlan?: number | null;
|
||||
routeSpeedFact?: number | null;
|
||||
sections?: Array<WellSectionDto> | null;
|
||||
companies?: Array<CompanyDto> | null;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { OperationDtoPaginationContainer } from '../models/OperationDtoPaginationContainer';
|
||||
import type { OperationDurationDto } from '../models/OperationDurationDto';
|
||||
import type { WellDepthToDayDto } from '../models/WellDepthToDayDto';
|
||||
import type { WellDepthToIntervalDto } from '../models/WellDepthToIntervalDto';
|
||||
@ -8,6 +9,39 @@ import { request as __request } from '../core/request';
|
||||
|
||||
export class AnalyticsService {
|
||||
|
||||
/**
|
||||
* Возвращает список операций на скважине за все время
|
||||
* @param wellId id скважины
|
||||
* @param skip для пагинации кол-во записей пропустить
|
||||
* @param take для пагинации кол-во записей
|
||||
* @param categoryIds список категорий
|
||||
* @param begin дата начала
|
||||
* @param end окончание
|
||||
* @returns OperationDtoPaginationContainer Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getOperationsByWell(
|
||||
wellId: number,
|
||||
skip: number,
|
||||
take: number = 32,
|
||||
categoryIds?: Array<number>,
|
||||
begin?: string,
|
||||
end?: string,
|
||||
): Promise<OperationDtoPaginationContainer> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/analytics/${wellId}/operationsByWell`,
|
||||
query: {
|
||||
'skip': skip,
|
||||
'take': take,
|
||||
'categoryIds': categoryIds,
|
||||
'begin': begin,
|
||||
'end': end,
|
||||
},
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает данные по скважине "глубина-день"
|
||||
* @param wellId id скважины
|
||||
@ -27,22 +61,22 @@ wellId: number,
|
||||
/**
|
||||
* Возвращает данные по глубине скважины за период
|
||||
* @param wellId id скважины
|
||||
* @param intervalHoursTimestamp количество секунд в необходимом интервале времени
|
||||
* @param workBeginTimestamp количество секунд в времени начала смены
|
||||
* @param intervalSeconds количество секунд в необходимом интервале времени
|
||||
* @param workBeginSeconds количество секунд в времени начала смены
|
||||
* @returns WellDepthToIntervalDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getWellDepthToInterval(
|
||||
wellId: number,
|
||||
intervalHoursTimestamp?: number,
|
||||
workBeginTimestamp?: number,
|
||||
intervalSeconds?: number,
|
||||
workBeginSeconds?: number,
|
||||
): Promise<Array<WellDepthToIntervalDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/analytics/${wellId}/wellDepthToInterval`,
|
||||
query: {
|
||||
'intervalHoursTimestamp': intervalHoursTimestamp,
|
||||
'workBeginTimestamp': workBeginTimestamp,
|
||||
'intervalSeconds': intervalSeconds,
|
||||
'workBeginSeconds': workBeginSeconds,
|
||||
},
|
||||
});
|
||||
return result.body;
|
||||
@ -75,22 +109,22 @@ end?: string,
|
||||
/**
|
||||
* Возвращает детальные данные по операциям на скважине за период
|
||||
* @param wellId id скважины
|
||||
* @param intervalHoursTimestamp количество секунд в необходимом интервале времени
|
||||
* @param workBeginTimestamp количество секунд в времени начала смены
|
||||
* @param intervalSeconds количество секунд в необходимом интервале времени
|
||||
* @param workBeginSeconds количество секунд в времени начала смены
|
||||
* @returns OperationDurationDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getOperationsToInterval(
|
||||
wellId: number,
|
||||
intervalHoursTimestamp?: number,
|
||||
workBeginTimestamp?: number,
|
||||
intervalSeconds?: number,
|
||||
workBeginSeconds?: number,
|
||||
): Promise<Array<OperationDurationDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/analytics/${wellId}/operationsToInterval`,
|
||||
query: {
|
||||
'intervalHoursTimestamp': intervalHoursTimestamp,
|
||||
'workBeginTimestamp': workBeginTimestamp,
|
||||
'intervalSeconds': intervalSeconds,
|
||||
'workBeginSeconds': workBeginSeconds,
|
||||
},
|
||||
});
|
||||
return result.body;
|
||||
|
56
src/services/api/services/ClusterService.ts
Normal file
@ -0,0 +1,56 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ClusterDto } from '../models/ClusterDto';
|
||||
import type { ClusterStatDto } from '../models/ClusterStatDto';
|
||||
import type { WellDto } from '../models/WellDto';
|
||||
import { request as __request } from '../core/request';
|
||||
|
||||
export class ClusterService {
|
||||
|
||||
/**
|
||||
* Получает список доступных пользователю кустов
|
||||
* @returns ClusterDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getClusters(): Promise<Array<ClusterDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/cluster`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение доступных пользователю скважин
|
||||
* @param idCluster
|
||||
* @returns WellDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getWells(
|
||||
idCluster: number,
|
||||
): Promise<Array<WellDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/cluster/${idCluster}`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение обопщенной статистики по кусту (лучшая/худшая скважина)
|
||||
* @param idCluster
|
||||
* @returns ClusterStatDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getStat(
|
||||
idCluster: number,
|
||||
): Promise<ClusterStatDto> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/cluster/${idCluster}/Stat`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ export class DataService {
|
||||
* @param wellId id скважины
|
||||
* @param begin дата начала выборки. По умолчанию: текущее время - intervalSec
|
||||
* @param intervalSec интервал времени даты начала выборки, секунды
|
||||
* @param approxPointsCount желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.
|
||||
* @param approxPointsCount жела<EFBFBD><EFBFBD>мое количество точек. Если в выборке точек будет больше, то выборка будет прорежена.
|
||||
* @returns DataSaubBaseDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
|
39
src/services/api/services/DepositService.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { ClusterDto } from '../models/ClusterDto';
|
||||
import type { DepositDto } from '../models/DepositDto';
|
||||
import { request as __request } from '../core/request';
|
||||
|
||||
export class DepositService {
|
||||
|
||||
/**
|
||||
* Получает список доступных пользователю месторождений
|
||||
* @returns DepositDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getDeposits(): Promise<Array<DepositDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/deposit`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает список доступных пользователю кустов месторождения
|
||||
* @param depositId
|
||||
* @returns ClusterDto Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getClusters(
|
||||
depositId: number,
|
||||
): Promise<Array<ClusterDto>> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/deposit/${depositId}`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
}
|
87
src/services/api/services/FileService.ts
Normal file
@ -0,0 +1,87 @@
|
||||
/* istanbul ignore file */
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
import type { FilePropertiesDtoPaginationContainer } from '../models/FilePropertiesDtoPaginationContainer';
|
||||
import { request as __request } from '../core/request';
|
||||
|
||||
export class FileService {
|
||||
|
||||
/**
|
||||
* Сохраняет переданные файлы и информацию о них
|
||||
* @param wellId id скважины
|
||||
* @param idCategory id категории файла
|
||||
* @param idUser id отправившего файл пользователя
|
||||
* @param requestBody
|
||||
* @returns number Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async saveFiles(
|
||||
wellId: number,
|
||||
idCategory?: number,
|
||||
idUser?: number,
|
||||
requestBody?: any,
|
||||
): Promise<number> {
|
||||
const result = await __request({
|
||||
method: 'POST',
|
||||
path: `/api/files/${wellId}/files`,
|
||||
query: {
|
||||
'idCategory': idCategory,
|
||||
'idUser': idUser,
|
||||
},
|
||||
body: requestBody,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает информацию о файлах для сква<EFBFBD><EFBFBD>ины в выбраной категории
|
||||
* @param wellId id скважины
|
||||
* @param skip для пагинации кол-во записей пропустить
|
||||
* @param take для пагинации кол-во записей взять
|
||||
* @param idCategory id категории файла
|
||||
* @param begin дата начала
|
||||
* @param end дата окончания
|
||||
* @returns FilePropertiesDtoPaginationContainer Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getFilesInfo(
|
||||
wellId: number,
|
||||
skip: number,
|
||||
take: number = 32,
|
||||
idCategory: number,
|
||||
begin?: string,
|
||||
end?: string,
|
||||
): Promise<FilePropertiesDtoPaginationContainer> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/files/${wellId}`,
|
||||
query: {
|
||||
'skip': skip,
|
||||
'take': take,
|
||||
'idCategory': idCategory,
|
||||
'begin': begin,
|
||||
'end': end,
|
||||
},
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает файл с диска на сервере
|
||||
* @param wellId id скважины
|
||||
* @param fileId id запрашиваемого файла
|
||||
* @returns string Success
|
||||
* @throws ApiError
|
||||
*/
|
||||
public static async getFile(
|
||||
wellId: number,
|
||||
fileId: number,
|
||||
): Promise<string> {
|
||||
const result = await __request({
|
||||
method: 'GET',
|
||||
path: `/api/files/${wellId}/${fileId}`,
|
||||
});
|
||||
return result.body;
|
||||
}
|
||||
|
||||
}
|
@ -116,7 +116,7 @@ end?: string,
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает даты самого старого и самого свежего отчетов в БД
|
||||
* Возвра<EFBFBD><EFBFBD>ает даты самого старого и самого свежего отчетов в БД
|
||||
* @param wellId id скважины
|
||||
* @returns DatesRangeDto Success
|
||||
* @throws ApiError
|
||||
|
@ -12,16 +12,21 @@ type ConnectionsDict = {
|
||||
[route: string]: HubConnection;
|
||||
};
|
||||
|
||||
//var baseUrl = `http://192.168.1.70:5000`
|
||||
var baseUrl = process.env.NODE_ENV === 'development'
|
||||
?'http://192.168.1.70:5000'
|
||||
:''
|
||||
|
||||
const Connections: ConnectionsDict = {
|
||||
'hubs/telemetry': new HubConnectionBuilder()
|
||||
.withUrl(`http://192.168.1.70:5000/hubs/telemetry`, ConnectionOptions)
|
||||
.withAutomaticReconnect()
|
||||
.build(),
|
||||
.withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)//
|
||||
.withAutomaticReconnect()
|
||||
.build(),
|
||||
|
||||
'hubs/reports': new HubConnectionBuilder()
|
||||
.withUrl(`http://192.168.1.70:5000/hubs/reports`, ConnectionOptions)
|
||||
.withAutomaticReconnect()
|
||||
.build()
|
||||
.withUrl(`${baseUrl}/hubs/reports`, ConnectionOptions)
|
||||
.withAutomaticReconnect()
|
||||
.build()
|
||||
}
|
||||
|
||||
let connectionPromise: Promise<void>
|
||||
@ -43,6 +48,21 @@ type handlerFunction = (...args: any[]) => void;
|
||||
|
||||
type cleanFunction = (...args: any[]) => void;
|
||||
|
||||
const MakeUnsubscribeFunction = (
|
||||
connection: HubConnection,
|
||||
methodName: string,
|
||||
groupName: (string|null)):cleanFunction => {
|
||||
return async() => {
|
||||
if(connection.state === HubConnectionState.Connected)
|
||||
{
|
||||
if(groupName)
|
||||
await connection.send('RemoveFromGroup', groupName)
|
||||
connection.off(methodName)
|
||||
}
|
||||
connection.stop()
|
||||
}
|
||||
}
|
||||
|
||||
/** Subscribe on some SignalR method (topic).
|
||||
* @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]);
|
||||
* @param {string} methodName name of the method
|
||||
@ -61,12 +81,7 @@ const Subscribe = (
|
||||
connection.on(methodName, handler)
|
||||
})
|
||||
|
||||
if(groupName)
|
||||
return () => {
|
||||
Connections[hubUrl].send('RemoveFromGroup', groupName)
|
||||
.finally(()=>Connections[hubUrl].off(methodName))
|
||||
}
|
||||
return () => Connections[hubUrl].off(methodName)
|
||||
return MakeUnsubscribeFunction(Connections[hubUrl],methodName,groupName)
|
||||
}
|
||||
|
||||
/** Invokes some SignalR method.
|
||||
|
@ -163,6 +163,7 @@ tr.table_row_size {
|
||||
}
|
||||
|
||||
.header-tree-select{
|
||||
width: 300px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
@ -48,3 +48,11 @@ code {
|
||||
monospace;
|
||||
}
|
||||
|
||||
.linkDocuments {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.linkDocuments:hover {
|
||||
color: #c32828;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.filter-group__heading {
|
||||
.filter-group-heading {
|
||||
margin: 5px auto;
|
||||
align-items: center;
|
||||
}
|
||||
|